 ,129
129
Resource Manager Definitions.

CONST
      resSysHeap    = 64;   { System or application heap? }
      resPurgeable  = 32;   { Purgeable resource? }
      resLocked     = 16;   { Load it in locked? }
      resProtected  = 8;    { Protected? }
      resPreload    = 4;    { Load in on OpenResFile? }
      resChanged    = 2;    { Resource changed? }

      mapReadOnly   = 128;  { Resource file read-only }
      mapCompact    = 64;   { Compact resource file }
      mapChanged    = 32;   { Write map out at update }

      resNotFound   = - 192; { Resource not found }
      resFNotFound  = - 193; { Resource file not found }
      addResFailed  = - 194; { AddResource failed }
      rmvResFailed  = - 196; { RmveResource failed }
      resAttrErr    = -198;  {attribute does not permit operation}
      mapReadErr    = -199;  {map does not permit operation}

Resources in 128 Ko ROM:

'CURS'  1   IBeamCursor
'CURS'  2   CrossCursor
'CURS'  3   PlusCursor
'CURS'  4   WatchCursor
'DRVR'  2   Printer Driver shell (.PRINT)
'DRVR'  3   Sound Driver  (.SOUND)
'DRVR'  4   Disk Driver  (.SONY)
'DRVR'  9   AppleTalk driver  (.MPP)
'DRVR'  A   AppleTalk driver  (.ATP)
'FONT'  0   Name of system font
'FONT'  C   System font
'MDEF'  0   Default menu definition procedure
'PACK'  4   Floating-Point Arithmetic Package
'PACK'  5   Transcendental Functions Package
'PACK'  7   Binary-Decimal Conversion Package
'SERD'  0   Serial Driver
'WDEF'  0   Default window definition function

TYPE

      ResType = PACKED ARRAY [1..4] OF CHAR;

\ ,130
130
QuickDraw Definitions.

CONST
      srcCopy       = 0; { the 16 transfer modes }
      srcOr         = 1;
      srcXor        = 2;
      srcBic        = 3;
      notSrcCopy    = 4;
      notSrcOr      = 5;
      notSrcXor     = 6;
      notSrcBic     = 7;
      patCopy       = 8;
      patOr         = 9;
      patXor        = 10;
      patBic        = 11;
      notPatCopy    = 12;
      notPatOr      = 13;
      notPatXor     = 14;
      notPatBic     = 15;

      { QuickDraw color separation constants }

      normalBit     = 0; { normal screen mapping }
      inverseBit    = 1; { inverse screen mapping }
      redBit        = 4; { RGB additive mapping }
      greenBit      = 3;
      blueBit       = 2;
      cyanBit       = 8; { CMYBk subtractive mapping }
      magentaBit    = 7;
      yellowBit     = 6;
      blackBit      = 5;

      blackColor    = 33; { colors expressed in these mappings }
      whiteColor    = 30;
      redColor      = 205;
      greenColor    = 341;
      blueColor     = 409;
      cyanColor     = 273;
      magentaColor  = 137;
      yellowColor   = 69;

      picLParen     = 0;   { standard picture comments }
      picRParen     = 1;

      iBeamCursor   = 1; {text selection cursor}
      crossCursor   = 2; {for drawing graphics}
      plusCursor    = 3; {for structured selection}
      watchCursor   = 4; {for indicating a long delay}

TYPE
      QDByte = SignedByte;
      QDPtr = Ptr; { blind pointer }
      QDHandle = Handle; { blind handle }
      Pattern = PACKED ARRAY [0..7] OF 0..255;
      Bits16 = ARRAY [0..15] OF INTEGER;
      VHSelect = (v, h);
      GrafVerb = (frame, paint, erase, invert, fill);
      StyleItem = (bold, italic, underline, outline, shadow, condense,
                    extend);
      Style = SET OF StyleItem;

      FontInfo = RECORD
                   ascent: INTEGER;
                   descent: INTEGER;
                   widMax: INTEGER;
                   leading: INTEGER;
                 END;

      Point = RECORD
                CASE INTEGER OF

                  0:
                    (v: INTEGER;
                     h: INTEGER);

                  1:
                    (vh: ARRAY [VHSelect] OF INTEGER);

              END;

      Rect = RECORD
               CASE INTEGER OF

                 0:
                   (top: INTEGER;
                    left: INTEGER;
                    bottom: INTEGER;
                    right: INTEGER);

                 1:
                   (topLeft: Point;
                    botRight: Point);
             END;

      BitMap = RECORD
                 baseAddr: Ptr;
                 rowBytes: INTEGER;
                 bounds: Rect;
               END;

      Cursor = RECORD
                 data: Bits16;
                 mask: Bits16;
                 hotSpot: Point;
               END;

      PenState = RECORD
                   pnLoc: Point;
                   pnSize: Point;
                   pnMode: INTEGER;
                   pnPat: Pattern;
                 END;

      PolyHandle = ^PolyPtr;
      PolyPtr = ^Polygon;
      Polygon = RECORD
                  polySize: INTEGER;
                  polyBBox: Rect;
                  polyPoints: ARRAY [0..0] OF Point;
                END;

      RgnHandle = ^RgnPtr;
      RgnPtr = ^Region;
      Region = RECORD
                 rgnSize: INTEGER; { rgnSize = 10 for rectangular }
                 rgnBBox: Rect;
                        { plus more data if not rectangular }
               END;

      PicHandle = ^PicPtr;
      PicPtr = ^Picture;
      Picture = RECORD
                  picSize: INTEGER;
                  picFrame: Rect;
                          { plus byte codes for picture content }
                END;

      QDProcsPtr = ^QDProcs;
      QDProcs = RECORD
                  textProc: Ptr;
                  lineProc: Ptr;
                  rectProc: Ptr;
                  rRectProc: Ptr;
                  ovalProc: Ptr;
                  arcProc: Ptr;
                  polyProc: Ptr;
                  rgnProc: Ptr;
                  bitsProc: Ptr;
                  commentProc: Ptr;
                  txMeasProc: Ptr;
                  getPicProc: Ptr;
                  putPicProc: Ptr;
                END;

      GrafPtr = ^GrafPort;
      GrafPort = RECORD
                   device: INTEGER;
                   portBits: BitMap;
                   portRect: Rect;
                   visRgn: RgnHandle;
                   clipRgn: RgnHandle;
                   bkPat: Pattern;
                   fillPat: Pattern;
                   pnLoc: Point;
                   pnSize: Point;
                   pnMode: INTEGER;
                   pnPat: Pattern;
                   pnVis: INTEGER;
                   txFont: INTEGER;
                   txFace: Style;
                   txMode: INTEGER;
                   txSize: INTEGER;
                   spExtra: Fixed;
                   fgColor: LongInt;
                   bkColor: LongInt;
                   colrBit: INTEGER;
                   patStretch: INTEGER;
                   picSave: Handle;
                   rgnSave: Handle;
                   polySave: Handle;
                   grafProcs: QDProcsPtr;
                 END;

    VAR
      thePort: GrafPtr;
      white: Pattern;
      black: Pattern;
      gray: Pattern;
      ltGray: Pattern;
      dkGray: Pattern;
      arrow: Cursor;
      screenBits: BitMap;
      randSeed: LongInt;

\ ,131
131
Font Manager Definitions.

CONST

      commandMark   = $11;
      checkMark     = $12;
      diamondMark   = $13;
      appleMark     = $14;

      systemFont    = 0;
      applFont      = 1;
      newYork       = 2;
      geneva        = 3;
      monaco        = 4;
      venice        = 5;
      london        = 6;
      athens        = 7;
      sanFran       = 8;
      toronto       = 9;
      cairo         = 11;
      losAngeles    = 12;
      times         = 20;
      helvetica     = 21;
      courier       = 22;
      symbol        = 23;
      mobile        = 24;

      propFont      = $9000;
      prpFntH       = $9001;
      prpFntW       = $9002;
      prpFntHW      = $9003;

      fixedFont     = $B000;
      fxdFntH       = $B001;
      fxdFntW       = $B002;
      fxdFntHW      = $B003;

      fontWid       = $ACB0;

TYPE

      FMInput = PACKED RECORD
                  family: INTEGER;
                  size: INTEGER;
                  face: Style;
                  needBits: BOOLEAN;
                  device: INTEGER;
                  numer: Point;
                  denom: Point;
                END;

      FMOutPtr = ^FMOutPut;

      FMOutPut = PACKED RECORD
                   errNum: INTEGER;
                   fontHandle: Handle;
                   bold: Byte;
                   italic: Byte;
                   ulOffset: Byte;
                   ulShadow: Byte;
                   ulThick: Byte;
                   shadow: Byte;
                   extra: SignedByte;
                   ascent: Byte;
                   descent: Byte;
                   widMax: Byte;
                   leading: SignedByte;
                   unused: Byte;
                   numer: Point;
                   denom: Point;
                 END;

      FontRec = RECORD
                  fontType: INTEGER;    { font type }
                  firstChar: INTEGER;   { ASCII code of first character }
                  lastChar: INTEGER;    { ASCII code of last character }
                  widMax: INTEGER;      { maximum character width }
                  kernMax: INTEGER;     { negative of maximum character kern }
                  nDescent: INTEGER;    { negative of descent }
                  fRectWidth: INTEGER;  { width of font rectangle }
                  fRectHeight: INTEGER; { height of font rectangle }
                  oWTLoc: INTEGER;      { offset to offset/width table }
                  ascent: INTEGER;      { ascent }
                  descent: INTEGER;     { descent }
                  leading: INTEGER;     { leading }
                  rowWords: INTEGER;    { row width of bit image / 2 }
                { bitImage:    ARRAY[1..rowWords,1..fRectHeight]
                                    OF INTEGER;
                  locTable:    ARRAY[firstChar..lastChar+2]
                                    OF INTEGER;
                  owTable:    ARRAY[firstChar..lastChar+2]
                                    OF INTEGER;
                  widthTable: ARRAY[firstChar..lastChar+2]
                                    OF INTEGER;
                  heightTable: ARRAY[firstChar..lastChar+2]
                                    OF INTEGER; }
                END;

      {new 128K ROM}

      FMetricRec = RECORD
                     ascent: Fixed;     {base line to top}
                     descent: Fixed;    {base line to bottom}
                     leading: Fixed;    {leading between lines}
                     widMax: Fixed;     {maximum character width}
                     wTabHandle: Fixed; {handle to font width table}
                   END;

      WidTable = RECORD
                   numWidths: INTEGER; {number of entries - 1}
                            {widList: ARRAY[1..numWidths] of WidEntry}
                 END;

      WidEntry = RECORD
                   widStyle: INTEGER; {style entry applies to}
                                      {widRec: ARRAY[firstChar..lastChar]
                                        of INTEGER}
                 END;

      AsscEntry = RECORD
                    fontSize: INTEGER;
                    fontStyle: INTEGER;
                    fontID: INTEGER; {font resource ID}
                  END;

      FontAssoc = RECORD
                    numAssoc: INTEGER; {number of entries - 1}
                            {asscTable: ARRAY[1..numAssoc] OF AsscEntry}
                  END;

      StyleTable = RECORD
                     fontClass: INTEGER;
                     offset: LongInt;
                     reserved: LongInt;
                     indexes: ARRAY [0..47] OF Byte;
                   END;

      NameTable = RECORD
                    stringCount: INTEGER;
                    baseFontName: STR255;
                                {strings: ARRAY[2..stringCount]  OF STRING}
                                {the lengths of the strings are arbitrary}
                  END;

      KernPair = RECORD
                   kernFirst: CHAR; {1st character of kerned pair}
                   kernSecond: CHAR; {2nd character of kerned pair}
                   kernWidth: INTEGER; {kerning in 1pt fixed format}
                 END;

      KernEntry = RECORD
                    kernLength: INTEGER; {length of this entry}
                    kernStyle: INTEGER; {style the entry applies to}
                             {kernRec: ARRAY[1..(kernLength/4)-1] OF KernPair}
                  END;

      KernTable = RECORD
                    numKerns: INTEGER; {number of kerning entries}
                            {kernList: ARRAY[1..numKerns] OF KernEntry}
                  END;

      WidthTable = PACKED RECORD
                     tabData: ARRAY [1..256] OF Fixed; {character widths}
                     tabFont: Handle; {font record used to build table}
                     sExtra: LongInt; {space extra used for table}
                     Style: LongInt; {extra due to style}
                     fID: INTEGER; {font family ID}
                     fSize: INTEGER; {font size request}
                     face: INTEGER; {style (face) request}
                     device: INTEGER; {device requested}
                     vInScale: Fixed; {scale factors requested}
                     hInScale: Fixed; {scale factors requested}
                     aFID: INTEGER; {actual font family ID for table}
                     fHand: Handle; {family record used to build up table}
                     usedFam: BOOLEAN; {used fixed point family widths}
                     aFace: Byte; {actual face produced}
                     vOutput: INTEGER; {vertical scale output value}
                     hOutput: INTEGER; {horizontal scale output value}
                     vFactor: INTEGER; {vertical scale output value}
                     hFactor: INTEGER; {horizontal scale output value}
                     aSize: INTEGER; {actual size of actual font used}
                     tabSize: INTEGER; {total size of table}
                   END;

      FamRec = RECORD
                 ffFlags: INTEGER; {flags for family}
                 ffFamID: INTEGER; {family ID number}
                 ffFirstChar: INTEGER; {ASCII code of 1st character}
                 ffLastChar: INTEGER; {ASCII code of last character}
                 ffAscent: INTEGER; {maximum ascent for 1pt font}
                 ffDescent: INTEGER; {maximum descent for 1pt font}
                 ffLeading: INTEGER; {maximum leading for 1pt font}
                 ffWidMax: INTEGER; {maximum widMax for 1pt font}
                 ffWTabOff: LongInt; {offset to width table}
                 ffKernOff: LongInt; {offset to kerning table}
                 ffStylOff: LongInt; {offset to style mapping table}
                 ffProperty: ARRAY [1..9] OF INTEGER; {style property info}
                 ffIntl: ARRAY [1..2] OF INTEGER; {for international use}
                 ffVersion: INTEGER; {version number}
                          {ffAssoc:    FontAssoc;} {font association table}
                          {ffWidthTab: WidTable;} {width table}
                          {ffStyTab:   StyleTable;} {style mapping table}
                          {ffKernTab:  KernTable;} {kerning table}
               END;

\ ,132
132
Event Manager Definitions.

CONST

      everyEvent    = - 1;
      NullEvent     = 0;
      mouseDown     = 1;
      mouseUp       = 2;
      keyDown       = 3;
      keyUp         = 4;
      autoKey       = 5;
      updateEvt     = 6;
      diskEvt       = 7;
      activateEvt   = 8;
      networkEvt    = 10;
      driverEvt     = 11;
      app1Evt       = 12;
      app2Evt       = 13;
      app3Evt       = 14;
      app4Evt       = 15;

      { event mask equates }
      mDownMask     = 2;
      mUpMask       = 4;
      keyDownMask   = 8;
      keyUpMask     = 16;
      autoKeyMask   = 32;
      updateMask    = 64;
      diskMask      = 128;
      activMask     = 256;
      networkMask   = 1024;
      driverMask    = 2048;
      app1Mask      = 4096;
      app2Mask      = 8192;
      app3Mask      = 16384;
      app4Mask      = - 32768;

      {to decipher event message for keyDown events}
      charCodeMask  = $000000FF;
      keyCodeMask   = $0000FF00;

      { modifiers }
      optionKey     = 2048; { Bit 3 of high byte }
      alphaLock     = 1024; { Bit 2 }
      ShiftKey      = 512;  { Bit 1 }
      CmdKey        = 256;  { Bit 0 }
      BtnState      = 128;  { Bit 7 of low byte is mouse button state }

      activeFlag    = 1;    { bit 0 of modifiers for activate event }

      {error for PostEvent}
      EvtNotEnb     = 1;

TYPE

      EventRecord = RECORD
                      what: INTEGER;
                      message: LongInt;
                      when: LongInt;
                      where: Point;
                      modifiers: INTEGER;
                    END;

      KeyMap = PACKED ARRAY [0..127] OF BOOLEAN;

\ ,133
133
Window Manager Definitions.

CONST

      {window messages}
      wDraw     = 0;
      wHit      = 1;
      wCalcRgns = 2;
      wNew      = 3;
      wDispose  = 4;
      wGrow     = 5;
      wDrawGIcon = 6;

      {types of windows}
      dialogKind    = 2;
      userKind      = 8;

      {desk pattern resource ID}
      deskPatID     = 16;

      {window definition procedure IDs}
      documentProc  = 0;
      dBoxProc      = 1;
      plainDBox     = 2;
      altDBoxProc   = 3;
      noGrowDocProc = 4;
      zoomDocProc   = 8;
      zoomNoGrow    = 12;
      rDocProc      = 16;

      {FindWindow Result Codes}
      inDesk        = 0;
      inMenuBar     = 1;
      inSysWindow   = 2;
      inContent     = 3;
      inDrag        = 4;
      inGrow        = 5;
      inGoAway      = 6;

      {new 128K ROM}
      inZoomIn      = 7;
      inZoomOut     = 8;

      {defProc hit test codes}
      wNoHit        = 0;
      wInContent    = 1;
      wInDrag       = 2;
      wInGrow       = 3;
      wInGoAway     = 4;

      {new 128K ROM}
      wInZoomIn     = 5;
      wInZoomOut    = 6;

      {axis constraints for DragGrayRgn call}
      noConstraint  = 0;
      hAxisOnly     = 1;
      vAxisOnly     = 2;

TYPE

      WindowPtr     = GrafPtr;
      WindowPeek    = ^WindowRecord;
      ControlHandle = ^ControlPtr; {for Control Manager}

      WStateData =  RECORD;
        userState:  Rect;   {user state}
        stdState:   Rect    {standard state}
      END;

      WindowRecord = RECORD
                       port: GrafPort;
                       windowKind: INTEGER;
                       visible: BOOLEAN;
                       hilited: BOOLEAN;
                       goAwayFlag: BOOLEAN;
                       spareFlag: BOOLEAN;
                       strucRgn: RgnHandle;
                       contRgn: RgnHandle;
                       updateRgn: RgnHandle;
                       windowDefProc: Handle;
                       dataHandle: Handle;
                       titleHandle: StringHandle;
                       titleWidth: INTEGER;
                       ControlList: ControlHandle;
                       nextWindow: WindowPeek;
                       windowPic: PicHandle;
                       refCon: LongInt;
                     END;

\ ,134
134
Control Manager Definitions.

CONST

      {control messages}
      drawCntl  = 0;
      testCntl  = 1;
      calcCRgns = 2;
      initCntl  = 3;
      dispCntl  = 4;
      posCntl   = 5;
      thumbCntl = 6;
      dragCntl  = 7;
      autoTrack = 8;

      {FindControl Result Codes}
      inButton      = 10;
      inCheckbox    = 11;
      inUpButton    = 20;
      inDownButton  = 21;
      inPageUp      = 22;
      inPageDown    = 23;
      inThumb       = 129;

      {control definition proc ID's}
      pushButProc   = 0;
      checkBoxProc  = 1;
      radioButProc  = 2;
      scrollBarProc = 16;

      useWFont      = 8;

TYPE
      ControlPtr = ^ControlRecord;

      ControlRecord = PACKED RECORD
                        nextControl: ControlHandle;
                        contrlOwner: WindowPtr;
                        contrlRect: Rect;
                        contrlVis: Byte;
                        contrlHilite: Byte;
                        contrlValue: INTEGER;
                        contrlMin: INTEGER;
                        contrlMax: INTEGER;
                        contrlDefProc: Handle;
                        contrlData: Handle;
                        contrlAction: ProcPtr;
                        contrlrfCon: LongInt;
                        contrlTitle: STR255;
                      END; {ControlRecord}


\ ,135
135
Menu Manager Definitions.

CONST
      noMark        = 0; { mark symbol for MarkItem }
      TextMenuProc  = 0;

      { menu defProc messages }
      mDrawMsg      = 0;
      mChooseMsg    = 1;
      mSizeMsg      = 2;

TYPE
      MenuPtr       = ^MenuInfo;
      MenuHandle    = ^MenuPtr;
      MenuInfo      = RECORD
                       menuId: INTEGER;
                       menuWidth: INTEGER;
                       menuHeight: INTEGER;
                       menuProc: Handle;
                       enableFlags: LongInt;
                       menuData: STR255;
                     END;

\ ,136
136
TextEdit Definitions.

CONST
      teJustLeft    = 0;
      teJustRight   = - 1;
      teJustCenter  = 1;

TYPE
      TERec = RECORD
                destRect: Rect;         {Destination rectangle}
                viewRect: Rect;         {view rectangle}
                selRect: Rect;          {Select rectangle}
                lineHeight: INTEGER;    {Current font lineheight}
                fontAscent: INTEGER;    {Current font ascent}
                selPoint: Point;        {Selection point(mouseLoc)}

                selStart: INTEGER;      {Selection start}
                selEnd: INTEGER;        {Selection end}

                active: INTEGER;        {<>0 if active}

                wordBreak: ProcPtr;     {Word break routine}
                clikLoop: ProcPtr;      {Click loop routine}

                clickTime: LongInt;     {Time of first click}
                clickLoc: INTEGER;      {Char. location of click}

                caretTime: LongInt;     {Time for next caret blink}
                caretState: INTEGER;    {On/active booleans}

                just: INTEGER;          {fill style}

                teLength: INTEGER;      {Length of text below}
                hText: Handle;          {Handle to actual text}

                recalBack: INTEGER;     {<>0 if recal in background}
                recalLines: INTEGER;    {Line being recal'ed}
                clikStuff: INTEGER;     {click stuff (internal)}

                crOnly: INTEGER;        {Set to -1 if CR line breaks only}

                txFont: INTEGER;        {Text Font}
                txFace: Style;          {Text Face}
                txMode: INTEGER;        {Text Mode}
                txSize: INTEGER;        {Text Size}

                inPort: GrafPtr;        {Grafport}

                highHook: ProcPtr;      {Highlighting hook}
                caretHook: ProcPtr;     {Highlighting hook}

                nLines: INTEGER;        {Number of lines}
                lineStarts: ARRAY [0..16000] OF INTEGER;
                                        {Actual line starts
                                        themselves}
              END;                      {RECORD}
      TEPtr = ^TERec;
      TEHandle = ^TEPtr;

      CharsHandle = ^CharsPtr;
      CharsPtr = ^Chars;
      Chars = PACKED ARRAY [0..32000] OF CHAR;

\ ,137
137
Dialog Manager Definitions.

CONST
      userItem  = 0;
      ctrlItem  = 4;
      btnCtrl   = 0;    { Low two bits specify what kind of control }
      chkCtrl   = 1;
      radCtrl   = 2;
      resCtrl   = 3;

      statText      = 8;        { Static text }
      editText      = 16;       { Editable text }
      iconItem      = 32;       { Icon item }
      picItem       = 64;       { Picture item }
      itemDisable   = 128;      { Disable item if set }

      ok        = 1;        { OK button is first by convention }
      cancel    = 2;        { Cancel button is second by convention }

      stopIcon      = 0;
      noteIcon      = 1;
      cautionIcon   = 2;

TYPE
      DialogPtr    = WindowPtr;
      DialogPeek   = ^DialogRecord;
      DialogRecord = RECORD
                       window: WindowRecord;
                       Items: Handle;
                       textH: TEHandle;
                       editField: INTEGER;
                       editOpen: INTEGER;
                       aDefItem: INTEGER;
                     END;

      DialogTHndl = ^DialogTPtr;
      DialogTPtr = ^DialogTemplate;
      DialogTemplate = RECORD
                         boundsRect: Rect;
                         procID: INTEGER;
                         visible: BOOLEAN;
                         filler1: BOOLEAN;
                         goAwayFlag: BOOLEAN;
                         filler2: BOOLEAN;
                         refCon: LongInt;
                         ItemsID: INTEGER;
                         title: STR255;
                       END;

      StageList = PACKED RECORD
                    boldItm4: 0..1;
                    boxDrwn4: BOOLEAN;
                    sound4: 0..3;
                    boldItm3: 0..1;
                    boxDrwn3: BOOLEAN;
                    sound3: 0..3;
                    boldItm2: 0..1;
                    boxDrwn2: BOOLEAN;
                    sound2: 0..3;
                    boldItm1: 0..1;
                    boxDrwn1: BOOLEAN;
                    sound1: 0..3;
                  END;

      AlertTHndl = ^AlertTPtr;
      AlertTPtr = ^AlertTemplate;
      AlertTemplate = RECORD
                        boundsRect: Rect;
                        ItemsID: INTEGER;
                        stages: StageList;
                      END;

\ ,138
138
Desk Manager Definitions.

CONST (Assembly-Language)

drvrFlags       EQU  $0     ; various flags and permissions [word]
drvrDelay       EQU  $2     ; # of ticks between systask calls [word]
drvrEMask       EQU  $4     ; event mask [word]
drvrMenu        EQU  $6     ; driver menu ID [word]
drvrOpen        EQU  $8     ; open routine offset [word]
drvrPrime       EQU  $A     ; prime routine offset [word]
drvrCtl         EQU  $C     ; control routine offset [word]
drvrStatus      EQU  $E     ; status routine offset [word]
drvrClose       EQU  $10    ; warmstart reset routine offset [word]
drvrName        EQU  $12    ; length byte and name of driver [string]

accEvent        EQU  $40    ; event message from SystemEvent
accRun          EQU  $41    ; run message from SystemTask
accCursor       EQU  $42    ; cursor message from SystemTask
accMenu         EQU  $43    ; menu message from SystemMenu
accUndo         EQU  $44    ; undo message from SystemEdit
accCut          EQU  $46    ; cut message from SystemEdit
accCopy         EQU  $47    ; copy message from SystemEdit
accPaste        EQU  $48    ; paste message from SystemEdit
accClear        EQU  $49    ; clear message from SystemEdit

goodBye         EQU  -1     ; goodbye message

\ ,139
139
Scrap Manager Definitions.

CONST
      noScrapErr    = - 100; {desk scrap isn't initialized}
      noTypeErr     = - 102;

TYPE
      ScrapStuff = RECORD
                     scrapSize: LongInt;
                     scrapHandle: Handle;
                     scrapCount: INTEGER;
                     scrapState: INTEGER;
                     scrapName: StringPtr;
                   END;
      pScrapStuff = ^ScrapStuff;

\ ,140
140
Toolbox Utilities Definitions.

CONST
      sysPatListID  = 0;    {ID of PAT# which contains 38 patterns}

      iBeamCursor   = 1;    {text selection cursor}
      crossCursor   = 2;    {for drawing graphics}
      plusCursor    = 3;    {for structured selection}
      watchCursor   = 4;    {for indicating a long delay}

TYPE
      Int64Bit = RECORD
                   hiLong: LongInt;
                   loLong: LongInt;
                 END;

      CursPtr = ^Cursor;
      CursHandle = ^CursPtr;

      PatPtr = ^Pattern;
      PatHandle = ^PatPtr;

\ ,141
141
Package Manager Definitions.

CONST
      listMgr   = 0; {list manager}
      dskInit   = 2; {Disk Initializaton}
      stdFile   = 3; {Standard File}
      flPoint   = 4; {Floating-Point Arithmetic}
      trFunc    = 5; {Transcendental Functions}
      intUtil   = 6; {International Utilities}
      bdConv    = 7; {Binary/Decimal Conversion}

\ ,142
142
Memory Manager Definition.

CONST
  MemFullErr    = - 108; { Not enough room in heap zone }
  NilHandleErr  = - 109; { Master Pointer was NIL in HandleZone or other }
  MemWZErr      = - 111; { WhichZone failed (applied to free block) }
  MemPurErr     = - 112; { trying to purge a locked or non-purgeable block }
  MemLockedErr  = - 117; { Block is locked }
  NoErr         = 0;     { All is well }

TYPE
      SignedByte    = - 128..127;   { any byte in memory }
      Byte          = 0..255;       { unsigned byte for fontmgr }
      Ptr           = ^SignedByte;  { blind pointer }
      Handle        = ^Ptr;         { pointer to a master pointer }
      ProcPtr       = Ptr;          { pointer to a procedure }
      Fixed         = LongInt;      { fixed point arithmetic type }

      Str255        = String[255];  { maximum string size }
      StringPtr     = ^Str255;      { pointer to maximum string }
      StringHandle  = ^StringPtr;   { handle to maximum string }

      Zone = RECORD
               BkLim: Ptr;
               PurgePtr: Ptr;
               HFstFree: Ptr;
               ZCBFree: LongInt;
               GZProc: ProcPtr;
               MoreMast: INTEGER;
               Flags: INTEGER;
               CntRel: INTEGER;
               MaxRel: INTEGER;
               CntNRel: INTEGER;
               MaxNRel: INTEGER;
               CntEmpty: INTEGER;
               CntHandles: INTEGER;
               MinCBFree: LongInt;
               PurgeProc: ProcPtr;
               SparePtr: Ptr;       { reserved for future }
               AllocPtr: Ptr;
               HeapData: INTEGER;
             END;
      THz   = ^Zone;    { pointer to the start of a heap zone }
      Size  = LongInt;  { size of a block in bytes }
      OSErr = INTEGER;  { error code }

      QElemPtr = ^QElem; {ptr to generic queue element}

\ ,143
143
Segment Loader Definitions.

CONST
      appOpen  = 0 ;  { Open the Document (s) }
      appPrint = 1 ;  { Print the Document (s)}
TYPE
      appFile = RECORD
                  vRefNum: INTEGER;
                  ftype: OSType;
                  versNum: INTEGER; {versNum in high byte}
                  fName: str255;
                END; {appFile}

\ ,144
144
OS Event Definitions.

CONST
      NullEvent     = 0;
      mouseDown     = 1;
      mouseUp       = 2;
      keyDown       = 3;
      keyUp         = 4;
      autoKey       = 5;
      updateEvt     = 6;
      diskEvt       = 7;
      activateEvt   = 8;
      networkEvt    = 10;
      driverEvt     = 11;
      app1Evt       = 12;
      app2Evt       = 13;
      app3Evt       = 14;
      app4Evt       = 15;

      { event mask equates }
      mDownMask     = 2;
      mUpMask       = 4;
      keyDownMask   = 8;
      keyUpMask     = 16;
      autoKeyMask   = 32;
      updateMask    = 64;
      diskMask      = 128;
      activMask     = 256;
      networkMask   = 1024;
      driverMask    = 2048;
      app1Mask      = 4096;
      app2Mask      = 8192;
      app3Mask      = 16384;
      app4Mask      = - 32768;

      {to decipher event message for keyDown events}
      charCodeMask  = $000000FF;
      keyCodeMask   = $0000FF00;

      { modifiers }
      optionKey     = 2048; { Bit 3 of high byte }
      alphaLock     = 1024; { Bit 2 }
      ShiftKey      = 512;  { Bit 1 }
      CmdKey        = 256;  { Bit 0 }
      BtnState      = 128;  { Bit 7 of low byte is mouse button state }

      activeFlag    = 1;    { bit 0 of modifiers for activate event }

      {error for PostEvent}
      EvtNotEnb     = 1;

TYPE
      EventRecord = RECORD
                      what: INTEGER;
                      message: LongInt;
                      when: LongInt;
                      where: Point;
                      modifiers: INTEGER;
                    END;

      evQEl = RECORD
                qLink: QElemPtr;
                qType: INTEGER;
                evtQwhat: INTEGER; {this part is identical to the EventRecord
                                    as...}
                evtQmessage: LongInt; {defined in ToolIntf}
                evtQwhen: LongInt;
                evtQwhere: Point;
                evtQmodifiers: INTEGER;
              END;

\ ,145
145
File Manager Definitions.

CONST
  DirFulErr     = - 33; { Directory full }
  DskFulErr     = - 34; { disk full }
  NSVErr        = - 35; { no such volume }
  IOErr         = - 36; { I/O error }
  BdNamErr      = - 37; { bad name }
  FNOpnErr      = - 38; { File not open }
  EOFErr        = - 39; { End of file }
  PosErr        = - 40; { tried to position to before start of file (r/w) }
  MFulErr       = - 41; { memory full(open) or file won't fit (load) }
  TMFOErr       = - 42; { too many files open }
  FNFErr        = - 43; { File not found }

  WPrErr        = - 44; { diskette is write protected }
  FLckdErr      = - 45; { file is locked }
  VLckdErr      = - 46; { volume is locked }
  FBsyErr       = - 47; { File is busy (delete) }
  DupFNErr      = - 48; { duplicate filename (rename) }
  OpWrErr       = - 49; { file already open with with write permission }
  ParamErr      = - 50; { error in user parameter list }
  RFNumErr      = - 51; { refnum error }
  GFPErr        = - 52; { get file position error }
  VolOffLinErr  = - 53; { volume not on line error (was Ejected) }
  PermErr       = - 54; { permissions error (on file open) }
  VolOnLinErr   = - 55; { drive volume already on-line at MountVol }
  NSDrvErr      = - 56; { no such drive (tried to mount a bad drive num) }
  NoMacDskErr   = - 57; { not a mac diskette (sig bytes are wrong) }
  ExtFSErr      = - 58; { volume in question belongs to an external fs }
  FSRnErr       = - 59; { file system rename error }
  BadMDBErr     = - 60; { bad master directory block }
  WrPermErr     = - 61; { write permissions error }

  lastDskErr    = - 64; { last in a range of disk errors }
  noDriveErr    = - 64; { drive not installed }
  offLinErr     = - 65; { r/w requested for an off-line drive }
  noNybErr      = - 66; { couldn't find 5 nybbles in 200 tries }
  noAdrMkErr    = - 67; { couldn't find valid addr mark }
  dataVerErr    = - 68; { read verify compare failed }
  badCkSmErr    = - 69; { addr mark checksum didn't check }
  badBtSlpErr   = - 70; { bad addr mark bit slip nibbles }
  noDtaMkErr    = - 71; { couldn't find a data mark header }
  badDCkSum     = - 72; { bad data mark checksum }
  badDBtSlp     = - 73; { bad data mark bit slip nibbles }
  wrUnderRun    = - 74; { write underrun occurred }
  cantStepErr   = - 75; { step handshake failed }
  tk0BadErr     = - 76; { track 0 detect doesn't change }
  initIWMErr    = - 77; { unable to initialize IWM }
  twoSideErr    = - 78; { tried to read 2nd side on a 1-sided drive }
  spdAdjErr     = - 79; { unable to correctly adjust disk speed }
  seekErr       = - 80; { track number wrong on address mark }
  sectNFErr     = - 81; { sector number never found on a track }
  firstDskErr   = - 84; { first in a range of disk errors }

  DirNFErr      = - 120; { Directory not found }
  TMWDOErr      = - 121; { No free WDCB available }
  BadMovErr     = - 122; { Move into offspring error }
  WrgVolTypErr  = - 123; { Wrong volume type error - operation not
                            supported for MFS}
  FSDSIntErr    = - 127; { Internal file system error }

  MaxSize       = $800000; { Max data block size is 8 megabytes }

      {finder constants}
      fOnDesk       = 1;
      fHasBundle    = 8192;
      fInvisible    = 16384;
      fTrash        = - 3;
      fDesktop      = - 2;
      fDisk         = 0;

      {io constants}

      {ioPosMode values}
      fsAtMark      = 0;
      fsFromStart   = 1;
      fsFromLEOF    = 2;
      fsFromMark    = 3;
      rdVerify      = 64;

      {ioPermission values}
      fsCurPerm     = 0;
      fsRdPerm      = 1;
      fsWrPerm      = 2;
      fsRdWrPerm    = 3;
      fsRdWrShPerm  = 4;

TYPE
  ParamBlkType = (IOParam, FileParam, VolumeParam, CntrlParam);

  OSType = PACKED ARRAY [1..4] OF CHAR; {same as rsrc mgr's Restype}

  FInfo = RECORD                {record of finder info}
            fdType: OSType;     {the type of the file}
            fdCreator: OSType;  {file's creator}
            fdFlags: INTEGER;   {flags ex. hasbundle,invisible,locked,
                                    etc.}
            fdLocation: Point;  {file's location in folder}
            fdFldr: INTEGER;    {folder containing file}
          END; {FInfo}


  FXInfo = RECORD
             fdIconID: INTEGER;         {Icon ID}
             fdUnused: ARRAY [1..4] OF INTEGER; {unused but reserved 8 bytes}
             fdComment: INTEGER;        {Comment ID}
             fdPutAway: LongInt;        {Home Dir ID}
           END;

  DInfo = RECORD
            frRect: Rect;       {folder rect}
            frFlags: INTEGER;   {Flags}
            frLocation: Point;  {folder location}
            frView: INTEGER;    {folder view}
          END;

  DXInfo = RECORD
             frScroll: Point;       {scroll position}
             frOpenChain: LongInt;  {DirID chain of open folders}
             frUnused: INTEGER;     {unused but reserved}
             frComment: INTEGER;    {comment}
             frPutAway: LongInt;    {DirID}
           END;


  ParamBlockRec = RECORD
  {12 byte header used by the file and IO system}
    qLink: QElemPtr;        {queue link in header}
    qType: INTEGER;         {type byte for safety check}
    ioTrap: INTEGER;        {FS: the Trap}
    ioCmdAddr: Ptr;         {FS: address to dispatch to}

             {common header to all variants}
    ioCompletion: ProcPtr; {completion routine addr (0 for
                            synch calls)}
    ioResult: OSErr;        {result code}
    ioNamePtr: StringPtr;   {ptr to Vol:FileName string}
    ioVRefNum: INTEGER;     {volume refnum (DrvNum for Eject and
                                MountVol)}

{different components for the different type of parameter blocks}
    CASE ParamBlkType OF
      IOParam:
        (ioRefNum: INTEGER;     {refNum for I/O operation}
         ioVersNum: SignedByte; {version number}
         ioPermssn: SignedByte; {Open: permissions (byte)}

         ioMisc: Ptr;           {Rename: new name}
                                {GetEOF,SetEOF: logical end of file}
                                {Open: optional ptr to buffer}
                                {SetFileType: new type}
         ioBuffer: Ptr;         {data buffer Ptr}
         ioReqCount: LongInt;   {requested byte count; also =
                                 ioNewDirID}
         ioActCount: LongInt;   {actual byte count completed}
         ioPosMode: INTEGER;    {initial file positioning}
         ioPosOffset: LongInt); {file position offset}

      FileParam:
        (ioFRefNum: INTEGER;        {reference number}
         ioFVersNum: SignedByte;    {version number}
         filler1: SignedByte;
         ioFDirIndex: INTEGER;      {GetFInfo directory index}
         ioFlAttrib: SignedByte;    {GetFInfo: in-use bit=7, lock
                                        bit=0}
         ioFlVersNum: SignedByte;   {file version number}
         ioFlFndrInfo: FInfo;       {user info}
         ioFlNum: LongInt;          {GetFInfo: file number; TF-
                                        ioDirID}
         ioFlStBlk: INTEGER;        {start file block (0 if none)}
         ioFlLgLen: LongInt;        {logical length (EOF)}
         ioFlPyLen: LongInt;        {physical lenght}
         ioFlRStBlk: INTEGER;       {start block rsrc fork}
         ioFlRLgLen: LongInt;       {file logical length rsrc fork}
         ioFlRPyLen: LongInt;       {file physical length rsrc fork}
         ioFlCrDat: LongInt;        {file creation date & time (32
                                        bits in secs)}
         ioFlMdDat: LongInt);       {last modified date and time}

      VolumeParam:
        (filler2: LongInt;
         ioVolIndex: INTEGER;   {volume index number}
         ioVCrDate: LongInt;    {creation date and time}
         ioVLsBkUp: LongInt;    {last backup date and time}
         ioVAtrb: INTEGER;      {volume attrib}
         ioVNmFls: INTEGER;     {number of files in directory}
         ioVDirSt: INTEGER;     {start block of file directory}
         ioVBlLn: INTEGER;      {GetVolInfo: length of dir in
                                    blocks}
         ioVNmAlBlks: INTEGER;  {GetVolInfo: num blks (of alloc
                                    size)}
         ioVAlBlkSiz: LongInt;  {GetVolInfo: alloc blk byte
                                    size}
         ioVClpSiz: LongInt;    {GetVolInfo: bytes to allocate at
                                    a time}
         ioAlBlSt: INTEGER;     {starting disk(512-byte) block in
                                    block map}
         ioVNxtFNum: LongInt;   {GetVolInfo: next free file
                                    number}
         ioVFrBlk: INTEGER);    {GetVolInfo: # free alloc blks
                                    for this vol}

      CntrlParam:
        (ioCRefNum: INTEGER;        {refNum for I/O operation}
         CSCode: INTEGER;           {word for control status code}
         CSParam: ARRAY [0..10] OF INTEGER); {operation-defined
                                                parameters}
  END; {ParamBlockRec}

  ParmBlkPtr = ^ParamBlockRec;

\ ,146
146
Printing Manager Definitions.

CONST
  iPrPgFract = 120; {Page scale factor. ptPgSize (below) is in units of
                     1/iPrPgFract }

  iPrPgFst      = 1; {Page range constants}
  iPrPgMax      = 9999;

  iPrRelease    = 3; {Current version number of the code.} {DC 7/23/84}
  iPfMaxPgs     = 128; {Max number of pages in a print file.}

  {Driver constants}
  iPrBitsCtl    = 4; {The Bitmap Print Proc's ctl number}
  lScreenBits   = $00000000; {The Bitmap Print Proc's Screen Bitmap
                                param}
  lPaintBits    = $00000001; {The Bitmap Print Proc's Paint [sq pix]
                                param}
  lHiScreenBits = $00000010; {The Bitmap Print Proc's Screen Bitmap
                                param}
  lHiPaintBits  = $00000011; {The Bitmap Print Proc's Paint [sq pix]
                                param}
  iPrIOCtl      = 5; {The Raw Byte IO Proc's ctl number}
  iPrEvtCtl     = 6; {The PrEvent Proc's ctl number}
  lPrEvtAll     = $0002FFFD; {The PrEvent Proc's CParam for the entire
                                screen}
  lPrEvtTop     = $0001FFFD; {The PrEvent Proc's CParam for the top
                                folder}
  iPrDevCtl     = 7;         {The PrDevCtl Proc's ctl number}
  lPrReset      = $00010000; {The PrDevCtl Proc's CParam for reset}
  lPrPageEnd    = $00020000; {The PrDevCtl Proc's CParam for end page}
  lPrLineFeed   = $00030000; {The PrDevCtl Proc's CParam for paper
                                advance}
  lPrLFSixth    = $0003FFFF; {The PrDevCtl Proc's CParam for 1/6 th inch
                                paper advance}
  lPrLFEighth   = $0003FFFE; {The PrDevCtl Proc's CParam for 1/8 th inch
                                paper advance}
  iFMgrCtl      = 8;         {The FMgr's Tail-hook Proc's ctl number}
  { [The Pre-Hook is the status call] }

  {Error Constants:}
  iMemFullErr   = - 108;
  iPrAbort      = 128;
  iIOAbort      = - 27;

  {The PrVars lo mem area:}
  pPrGlobals    = $00000944;
  bDraftLoop    = 0;
  bSpoolLoop    = 1;
  bUser1Loop    = 2;
  bUser2Loop    = 3;

  {The Currently supported printers:}
  bDevCItoh     = 1;
  iDevCItoh     = $0100; {CItoh}
  bDevDaisy     = 2;
  iDevDaisy     = $0200; {Daisy}
  bDevLaser     = 3;
  iDevLaser     = $0300; {Laser}

TYPE
  TPRect = ^Rect;       {A Rect Ptr}
  TPBitMap = ^BitMap;   {A BitMap Ptr}

  {NOTE: Changes will also affect: PrEqu, TCiVars & TPfVars}
  TPrVars = RECORD {4 longs for printing, see SysEqu for location.}
              iPrErr: Integer; {Current print error. Set to iPrAbort to
                                    abort printing.}
              bDocLoop: SignedByte; {The Doc style: Draft, Spool, ..,
                                    and .. Currently use low 2 bits; the
                                    upper 6 are for flags.}
              bUser1: SignedByte; {Spares used by the print code}
              lUser1: LongInt;
              lUser2: LongInt;
              lUser3: LongInt;
            END;
  TPPrVars = ^TPrVars;

  TPrInfo = RECORD {Print Info Record: The parameters needed for page
                    composition.}
              iDev: Integer; {Font mgr/QuickDraw device code}
              iVRes: Integer; {Resolution of device, in device
                                coordinates}
              iHRes: Integer; { ..note: V before H => compatable with
                                Point.}
              rPage: Rect; {The page (printable) rectangle in device
                            coordinates.}
            END;
  TPPrInfo = ^TPrInfo;

  {These are types of paper feeders.}
  TFeed = (feedCut, feedFanfold, feedMechCut, feedOther);

  TPrStl = RECORD {Printer Style: The printer configuration and usage
                   information.}
             wDev: Integer; {The device (driver) number. Hi byte=RefNum,
                                Lo byte=variant. f0 = fHiRes,
                                f1 = fPortrait, f2 = fSqPix,
                                f3 = f2xZoom, f4 = fScroll.}
             iPageV: Integer; {paper size in units of 1/iPrPgFract}
             iPageH: Integer; { ..note: V before H => compatable with
                                Point.}
             bPort: SignedByte; {The IO port number. Refnum?}
             feed: TFeed; {paper feeder type.}
           END;
  TPPrStl = ^TPrStl;

  {Banding data structures. Not of general interest to Apps.}
  TScan = {Band Scan direction Top-Bottom, Left-Right, etc.}
  (scanTB, scanBT, scanLR, scanRL);

  TPrXInfo = RECORD {The print time eXtra information.}
               iRowBytes: Integer; {The Band's rowBytes.}
               iBandV: Integer; {Size of band, in device coordinates}
               iBandH: Integer; { ..note: V before H => compatible with
                                 Point.}
               iDevBytes: Integer; {Size for allocation. May be more
                                    than rBounds size!}
               iBands: Integer; {Number of bands per page.}

               bPatScale: SignedByte; {Pattern scaling}
               bULThick: SignedByte; {3 Underscoring parameters}
               bULOffset: SignedByte;
               bULShadow: SignedByte;

               scan: TScan; {Band scan direction}
               bXInfoX: SignedByte; {An eXtra byte.}
             END;
  TPPrXInfo = ^TPrXInfo;

  TPrJob = RECORD {Print Job: Print "form" for a single print request.}
             iFstPage: Integer; {Page Range.}
             iLstPage: Integer;
             iCopies: Integer; {No. copies.}
             bJDocLoop: SignedByte; {The Doc style: Draft, Spool, ..,
                                        and ..}
             fFromUsr: Boolean; {Printing from an User's App (not PrApp)
                                    flag}
             pIdleProc: ProcPtr; {The Proc called while waiting on IO
                                    etc.}
             pFileName: StringPtr; {Spool File Name: NIL for default.}
             iFileVol: Integer; {Spool File vol, set to 0 initially}
             bFileVers: SignedByte; {Spool File version, set to 0
                                        initially}
             bJobX: SignedByte; {An eXtra byte.}
           END;
  TPPrJob = ^TPrJob;

  TPrint = RECORD {The universal 120 byte printing record}
             iPrVersion: Integer; {2} {Printing software version}
             PrInfo: TPrInfo; {14} {the PrInfo data associated with the
                                    current style.}
             rPaper: Rect; {8} {The paper rectangle [offset from rPage]}
             PrStl: TPrStl; {8} {This print request's style.}
             PrInfoPT: TPrInfo; {14} {Print Time Imaging metrics}
             PrXInfo: TPrXInfo; {16} {Print-time (expanded) Print info
                                      record.}
             PrJob: TPrJob; {20} {The Print Job request}
                  {82} {Total of the above; 120-82 = 38 bytes needed to
                        fill 120}
             PrintX: ARRAY [1..19] OF Integer; {Spare to fill to 120
                                                bytes!}
           END;
  TPPrint = ^TPrint;
  THPrint = ^TPPrint;

{Printing Graf Port. All printer imaging, whether spooling, banding, etc, happens "thru" a GrafPort.}
  TPrPort = RECORD {This is the "PrPeek" record.}
              GPort: GrafPort; {The Printer's graf port.}
              GProcs: QDProcs; {..and its procs}

              lGParam1: LongInt; {16 bytes for private parameter storage.}
              lGParam2: LongInt;
              lGParam3: LongInt;
              lGParam4: LongInt;

              fOurPtr: Boolean; {Whether the PrPort allocation was done by
                                 us.}
              fOurBits: Boolean; {Whether the BitMap allocation was done by
                                  us.}
            END;
  TPPrPort = ^TPrPort;

  TPrStatus = RECORD {Print Status: Print information during printing.}
                iTotPages: Integer; {Total pages in Print File.}
                iCurPage: Integer; {Current page number}
                iTotCopies: Integer; {Total copies requested}
                iCurCopy: Integer; {Current copy number}
                iTotBands: Integer; {Total bands per page.}
                iCurBand: Integer; {Current band number}
                fPgDirty: Boolean; {True if current page has been written to.}
                fImaging: Boolean; {Set while in band's DrawPic call.}
                hPrint: THPrint; {Handle to the active Printer record}
                pPrPort: TPPrPort; {Ptr to the active PrPort}
                hPic: PicHandle; {Handle to the active Picture}
              END;
  TPPrStatus = ^TPrStatus;

{PicFile = a TPfHeader followed by n QuickDraw Pics (whose PicSize is invalid!)}
  TPfPgDir = RECORD
               iPages: Integer;
               lPgPos: ARRAY [0..iPfMaxPgs] OF LongInt;
             END;
  TPPfPgDir = ^TPfPgDir;
  THPfPgDir = ^TPPfPgDir;

  TPfHeader = RECORD {Print File header.}
                Print: TPrint;
                PfPgDir: TPfPgDir;
              END;
  TPPfHeader = ^TPfHeader;
  THPfHeader = ^TPPfHeader; {Note: Type compatable with an hPrint.}

{ This is the Printing Dialog Record. Only used by folks appending their own dialogs. }
  TPrDlg = RECORD {Print Dialog: The Dialog Stream object.}
             Dlg: DialogRecord; {The Dialog window}
             pFltrProc: ProcPtr; {The Filter Proc.}
             pItemProc: ProcPtr; {The Item evaluating proc.}
             hPrintUsr: THPrint; {The user's print record.}
             fDoIt: Boolean;
             fDone: Boolean;
             lUser1: LongInt; {Four longs for user's to hang global data.}
             lUser2: LongInt;
             lUser3: LongInt;
             lUser4: LongInt;
              {  ...Plus more stuff needed by the particular printing dialog.}
           END;
  TPPrDlg = ^TPrDlg; {== a dialog ptr}
\ ,147
147
Device Manager Definitions.

\ ,148
148
Disk Driver Definitions.

\ ,149
149
Sound Driver Definitions.
\ ,154
154
List Manager Definitions.

CONST

{ Masks for selection flags (selFlags) }

    LOnlyOne = -128;        { 0 = multiple selections, 1 = one }
    LExtendDrag = 64;       { 1 = drag select without shift key }
    LNoDisjoint = 32;       { 1 = turn off selections on click }
    LNoExtend = 16;         { 1 = don't extend shift selections }
    LNoRect = 8;            { 1 = don't grow (shift,drag) selection as
                                rect }
    LUseSense = 4;          { 1 = shift should use sense of start cell }
    LNoNilHilite = 2;       { 1 = don't hilite empty cells }

{ Masks for other flags (listFlags) }

    LDoVAutoscroll = 2;     { 1 = allow vertical autoscrolling }
    LDoHAutoscroll = 1;     { 1 = allow horizontal autoscrolling }

{ Messages to list definition procedure }

    LInitMsg = 0;           { tell drawing routines to init themselves }
    LDrawMsg = 1;           { draw (and de/select) the indicated data }
    LHiliteMsg = 2;         { invert hilite state of specified cell }
    LCloseMsg = 3;          { shut down, the list is being disposed }

TYPE

    Cell = Point;

    dataArray  = PACKED ARRAY[0..32000] OF Char;
    dataPtr    = ^dataArray;
    dataHandle = ^dataPtr;

    ListPtr    = ^ListRec;
    ListHandle = ^ListPtr;
    ListRec    = RECORD
            rView : Rect;               {Rect in which we are viewed}
            port : GrafPtr;             {Grafport that owns us}
            indent : Point;             {Indent pixels in cell}
            cellSize : Point;           {Cell size}
            visible : Rect;             {visible row/column bounds}
            vScroll : ControlHandle;    {vertical scroll bar (or NIL)}
            hScroll : ControlHandle;    {horizontal scroll bar (or NIL)}
            selFlags : SignedByte;      { defines selection characteristics
            LActive : Boolean;          { active or not }
            LReserved : SignedByte;     { internally used flags }
            listFlags : SignedByte;     { other flags }
            clikTime : Longint;         { save time of last click }
            clikLoc : Point;            { save position of last click }
            mouseLoc : Point;           { current mouse position }
            LClikLoop : Ptr;            { routine called repeatedly during
                                        ListClick }
            lastClick : Cell;           { the last cell clicked in }
            refCon : Longint;           { reference value }
            listDefProc : Handle;       { Handle to the defProc }
            userHandle : Handle;        { General purpose handle for user}
            dataBounds : Rect;          { Total number of rows/columns}
            cells : dataHandle;         { Handle to data}
            maxIndex : Integer;         { index past the last element}
            cellArray : ARRAY[1..1] OF Integer;     { offsets to elements }
        END;
\ InitResources
1
FUNCTION InitResources : INTEGER;

    InitResources is called by the system whcn it starts up, and should
not be called by the application. It initializes the Resource Manager,
opens the system resource file, reads the resource map from the file
into memory, and returns a reference number for the file.

(note)
    The application doesn't need the reference number for the 
    system resource file, because every Resource Manager
    routine that has a reference number as a parameter
    interprets ¯ to mean the system resource file.


\ RsrcZoneInit
1
PROCEDURE RsrcZoneInit;

    RsrcZoneInit is called automatically when your application starts
up, to initialize the resource map read from the system resource file;
normally you'll have no need to call it directly. It "cleans up" after
any resource access that may have been done by a previous application.
First it closes all open resource files except the system resource
file. Then, for every system resource that was read into the
application heap (that is, whose resSysHeap attribute is ¯), it
replaces the handle to that resource in the resource map with NIL.
This lets the Resource Manager know that the resource will have to be
read in again (since the previous application heap is no longer
around).


\ CreateResFile
1
PROCEDURE CreateResFile (fileName: Str255);

    CreateResFile creates a resource file containing no resource data or
copy of the file's directory entry. If there's no file at all with the
given name, it also creates an empty data fork for the file. If
there's already a resource file with the given name (that is, a
resource form that isn't empty), CreateResFile will do nothing and the 
ResError function will return an appropriate Operating System result
code.

(note)
    Before you can work with the resource file, you need to
    open it with OpenResFile.


\ OpenResFile
1
FUNCTION OpenResFile (fileName: Str255) : INTEGER;

    OpenResFile opens the resource file having the given name and makes
it the current resource file. It reads the resource map from the file
into memory and returns a reference number for the file. It also reads
in every resource whose resPreload attribute is set. If the resource
file is already open, it doesn't make it the current resource file; it
simply returns the reference number.

(note)
    You don't have to call OpenResFile to open the system
    Resource file or the application's resource file, because
    they're opened when the system and the application start
    up, respectively. To get the reference number of the
    application's resource file, you can call CurResFile
    after the application starts up (before you open any
    other resource file).

    If the file can't be opened, OpenResėile will return -1 and the
ResError function will return an appropriate Operating System result
code. For example, an error occurs if there's no resource file with 
the given name.

\ CloseResFile
1
PROCEDURE CloseResFile (refNum: INTEGER);

    Given the reference number of a resource file, CloseResFile does the
following:

    - updates the resource file by calling the UpdateResFile procedure

    - for each resource in the resource file, releases the memory it
      occupies by calling the ReleaseResource procedure

    - releases the memory occupied by the resource map

    - closes the resource file

    If there's no resource file open with the given reference number,
CloseResFile will do nothing and the ResError function will return the
result code resFNotFound. A refNum of ¯ represents the system resource
file, but if you ask to close this file, CloseResFile first closes all
other open resource files.

    A CloseResFile of every open resource file except the system
resource file is done automatically when the application terminates. So
you only need to call CloseResFile if you want to close the system
resource file, or if you want to close any resource file before the
application terminates.


\ ResError
1
FUNCTION ResError : INTEGER;

    Called after one of the various Resource Manager routines that may
result in an error condition, ResError returns a result code
identifying the error, if any. If no error occurred, it returns the
result code

    CONST  noErr = ¯; {no error}

    If an error occurred at the Operating System level, it returns an
Operating System result code, such as the File Manager "disk I/O" error
or the Memory Manager "out of memory" error. (See the File Manager and
Memory Manager manuals for a list of the result codes.)  If an error
happened at the Resource Manager level, ResError returns one of the
following result codes:

    CONST   resNotFound  =  -192;   {resource not found}
        resFNotFound =  -193;   {resouce file not found}
        addResFailed =  -194;   {AddResource failed}
        rmvResFailed =  -196;   {RmveResource failed}

    Each routine description tells which errors may occur for that
routine. You can also check for an error after system startup, which
calls InitResources, and application startup, which opens the
application's resource file.


\ CurResFile
1
FUNCTION CurResFile  : INTEGER;

    CurResFile returns the reference number of the current resource file
You can call it when the application starts up to get the reference
number of its resource file.

(note)
    If the system resource file is the current resource file,
    CurResFile returns the actual reference number of the
    system reference file (found in the global variable
    SysMap). You needn't worry about this number being used 
    (instead of ¯ in the routines that require a reference
    number; these routines recognize both ¯ and the actual
    reference number as referring to the system resource
    file.

\ HomeResFile
1
FUNCTION HomeResFile  (theResource: Handle)  :  INTEGER

    Given a handle to a resource, HomeResFile returns the reference
number of the resource file containing that resource. If the given
handle isn't a handle to a resource, HomeResFile will return -1 and the 
ResError function will return the result code resNotFound.


\ UseResFile
1
PROCEDURE UseResFile  (refNum:  INTEGER);

    Given the reference number of a resource file, UseResFile sets the
current resource file to that file. If there's no resource file open
with the given reference number, UseResFile will do nothing and the
ResError function will return the result code resFNotFound. A refNum
of ¯ represents the system resource file.

    Open resource files are arranged as a linked list; the most recently
opened file is at the end of the list and is the first one to be
searched. UseResFile lets you start the search with a file opened
earlier; the file(s) following it on the list ate then left out of the
search process. This is best understood with an example. Assume there
are four open resource files (R¯ through R3); the search order is R3,
R2, R1, R¯. If you call UseResFile(R2), the search order becomes R2,
R1, R¯; R3 is no longer searched. If you then open a fifth resource
file (R4), it's added to the end of the list and the search order
becomes R4, R3, R2, R1, R¯.

    This procedure is useful if you no longer want to override a system
resource with one by the same name in your application's resource file. 
You can call UseResFile(¯) to leave the application resource file out
of the search, causing only the system resource file to be searched.

(warning)
    Early versions of some desk accessories may, upon
    closing, always set the current resource file to the one
    opened just prior to the accessory, ignoring any
    additional resource files that may have been opened while
    the accessory was in use. To be safe, whenever desk
    accessories may have been in use, call UseResFile to
    ensure access to resource files opened after accessories.


\ CountTypes
1
FUNCTION CountTypes : INTEGER;

    CountTypes returns the number of resource types in all open resource
files.


\ GetIndType
1
PROCEDURE GetIndType (VAR theType: ResType; index: INTEGER);

    Given an index ranging from 1 to CountTypes (above, GetIndType
returns a resource type in theType. Called repeatedly over the entire
range  for the index, it returns all the resource types in all open
resource files. If the given index isn't in the range from 1 to
CountTypes,  GetIndType returns four NUL characters (ASCII code ¯).


\ SetResLoad
1
PROCEDURE SetResLoad (load: BOOLEAN);

    Normally, the routines that return handles to resources read the
resource data into memory if it's not already in memory.
SetResLoad(FALSE) affects all those routines so that they will not read
the resource data into memory and will return an empty handle.
Resources whose resPreload attrribute is set will still be read in,
however, when a resource file is opened. SetResLoad(TRUE) restores the
normal state.

(warning)
    If you call SetResLoad(FALSE), be sure to restore the
    normal state as soon as possible, because other parts of
    the Toolbox that call the Resource Manager rely on it.


\ CountResources
1
FUNCTION CountResources (theType: ResType) : INTEGER;

    CountResources returns the total number of resources of the given
type in all open resource files.


\ GetIndResource
1
FUNCTION GetIndResource (theType: ResType; index: INTEGER) : Handle;

    Given an index ranging from 1 to CountResources(theType),
GetIndResource returns a handle to a resource of the given type (see
CountResources, above). Called repeatedly over the entire range for
the index, it returns handles to all resources of the given type in all
open resource files. GetIndResource reads the resource data into
memory if it's not already in memory, unless you've called
SetResLoad(FALSE).

(warning)
    The handle returned will be an empty handle if you've
    called SetResLoad(FALSE) (and the data isn't already in 
    memory). The handle will become empty if the resource
    data for a purgeable resource is read in but later
    purged. (You can test for an empty handle with, for
    example, myHndl^= NIL.)  To read in the data and make
    the handle no longer be empty, you can call LoadResource.

    GetIndResource returns handles for all resources in the most
recently opened resource file first, and then for those in the resource
files opened before it, in the reverse of the order that they were
opened. If you want to find out how many resources of a given type are
in a particular resource file, you can do so as follows:  Call
GetIndResource repeatedly with the index ranging from 1 to the number
of resources of that type. Pass each handle returned by GetIndResource
to HomeResFile and count all occurrences where the reference number
returned is that of the desired file. Be sure to start the index from
1, and to call SetResLoad(FALSE) so the resources won't be read in.

(note)
    The UseResFile procedure affects which file the Resource
    Manager searches first when looking for a particular
    resource but not when getting indexed resources  with
    GetIndResource.

    If the given index isn't in the range from 1 to
CountResources(theType), GetIndResource returns NIL and the ResError
function will return the result code resNotFound. GetIndResource also
returns NIL if the resource is to be read into memory but won't fit; in
this case, ResError will return an appropriate Operating System result
code.


\ GetResource
1
FUNCTION Get Resource (theType: ResType; the ID: INTEGER) : Handle;

    GetResource returns a handle to the resource having the given type
and ID number, reading the resource data into memory if it's not already
in memory and if you haven't called SetResLoad(FALSE) (see the warning 
aboove for GetIndResource). GetResource looks in the current resource
file and all resource files opened before it, in the reverse of the
order that they were opened; the system resource file is searched last.
If it doesn't find the resource, GetResource returns NIL and the 
ResError function will return the result code resNotFound. GetResource
also returns NIL if the resource is to be read into memory but won't 
fit; in this case, ResError will return an appropriate Operating System
result code.


\ GetNamedResource
1
FUNCTION GetNamedResource (theType: ResType; name: Str255) : Handle;

    GetNamedResource is the same as GetResource (above) except that you
pass a resource name instead of an ID number.


\ LoadResource
1
PROCEDURE LoadResource (theResource: Handle);

    Given a handle to a resource (returned by GetIndResource,
GetResource, or GetNamedResource), LoadResource reads that resource into
memory. It does nothing if the resource is already in memory or if the
given handle isn't a handle to a resource; in the latter case, the
ResError function will return the result code resNotFound. Call this
procedure if you want to access the data for a resource through its
handle and either you've called SetResLoad(FALSE) or if the resource is
purgeable.

    If you've changed the resource data for a purgeable resource and the 
resource is purged before being written to the resource file, the
changes will be lost; LoadResource will reread the original resource
from the resource file. See the descriptions of ChangedResource and
SetResPurge for information about how to ensure that changes made to
purgeable resources will be written to the research file.


\ ReleaseResource
1
PROCEDURE ReleaseResource (theResource: Handle);

    Given a handle to a resource, ReleaseResource releases the memory
occupied by the resource data, if any, and replaces the handle to that
resource in the resource map with NIL. (See Figure 7.)  The given
handle will no longer be recognized as a handle to a resource; if the
Resource Manager is subsequently called to get the released resource, a
new handle will be allocated. Use this procedure only after you're
completely through with a resource.


\ Detach Resource
1
PROCEDURE DetachResource (theResource: Handle);

    Given a handle to a resource, DetachResource replaces the handle to
that resource in the resource map with NIL. (See Figure 7 above.)  The
given handle will no longer be recognized as a handle to a resource; if
the Resource Manager is subsequently called to get the detached
resource, a new handle will be allocated.

    DetachResource is useful if you want the resource data to be
accessed only by yourself through the given handle and not by the
Resource Manager. DetachResource is also useful in the unusual case
that you don't want a resource to be released when a resource file is
closed. To copy a resource, you can call DetachResource followed by
AddResource (with a new resource ID).

    If the given handle isn't a handle to a resource, DetachResopurce
will  do nothing and the ResError function will return the result code
resNotFound.


\ UniqueID
1
FUNCTION UniqueID (theType: ResType) : INTEGER;

    UniqueID returns an ID number greater than ¯ that isn't currently
assigned to any resource of the given type in any open resource file.
Using this number when you add a new resource to a resource file
ensures that you won't duplicate a resource ID and override an existing 
resource.

(warning)
    It's possible that UniqueID will return an ID in the 
    range reserved for system resources (¯ to 127). You
    should check that the ID returned is greater than 127; if
    it isn't, call UniqueID again.


\ GetResInfo
1
PROCEDURE GetResInfo (theResource: Handle; VAR the ID: INTEGER; VAR
        theType: ResType; VAR name: Str255);

    Given a handle to a resource, GetResInfo returns the ID number,
type, and name of the resource. If the given handle isn't a handle to a 
resource, GetResInfo will do nothing and the ResError function will
return the result code resNotFound.


\ GetResAttrs
1
FUNCTION GetResAttrs (theResource: Handle) : INTEGER;

    Given a handle to a resource, GetResAttrs returns the resource
attributes for the resource. (Resource attributes are described above
under "Resource References".)  If the given handle isn't a handle to a
resource, GetResAttrs will do nothing and the ResError function will
return the result code resNotFound.


\ SizeResource
1
FUNCTION SizeResource (the Resource: Handle) : LONGINT;

    Given a handle to a resource, Size Resource returns the size in
bytes of the resource in the resource file. If the given handle isn't a
handle  to a resource, SizeResource will return -1 and the ResError
function will return the result code resNotFound. It's a good idea to
call SizeResource and ensure that sufficient space is available before
reading a resource into memory.


\ SetResInfo
1
PROCEDURE SetResInfo (theResource: Handle; theID: INTEGER;
                        name: Str255);

    Given a handle to a resource, SetResInfo changes the ID number and
name of the resource to the given ID number and name.
    _______________________________________________________________
    Assembly-language note:  If you pass NIL for the name parameter,
    the name will not be changed.
    _______________________________________________________________

(warning)
    It's a dangerous practice to change the ID number and
    name of a system resource, because other applications may
    already access the resource and may no longer work
    properly.

    The change will be written to the resource file when the file is
updated if you follow SetResInfo with a call to ChangedResource.

(warning)
    Even if you don't call Changed Resource for this resource,
    the change may be written to the resource file when the
    file is updated. If you've ever called ChangedResource
    for any resource in the file, or if you've added or 
    removed a resource, the Resource Manager will write out
    the entire resource map when it updates the file, so all
    changes made to resource information in the map will
    become permanent. If you want any of the changes to be
    temprary, you'll have to restore the original 
    information before the file is updated.

SetResInfo does nothing in the following cases:

    - The resProtected attribute for the resource is set.

    - The given handle isn't a handle to a resource. The ResError
      function will return the result code resNotFound.

    - The resource map becomes too large to fit in memory (which can
      happen if a name is passed) or sufficient space for the modified
      resource file can't be reserved on the disk. ResError will return 
      an appropriate Operating System result code.


\ SetResAttrs
1
PROCEDURE SetResAttrs (theResource: Handle; attrs: INTEGER);

    Given a handle to a resource, SetResAttrs sets the resource
attributes for the resource to attrs. (Resource attributes are
described above under "Resource Refererence".)  The resProtected
attribute takes effect immediately; the others take effect the next time
the resource is read in.

(warning)
    Do not use SetResAttrs to set the resChanged attribute;
    you must call Changed Resource instead. Be sure that the
    attrs parameter passed to SetResAttrs doesn't change the 
    current setting of this attribute.

    The attributes set with SetResAttrs will be written to the resource
file when the file is updated if you follow SetResAttrs with a call to
ChangedResource. However, even if you don't call ChangedResource for
this resource, the change may be written to the resource file when the
file is updated. See the last warning for SetResInfo (above).

    If the given handle isn't a handle to a resource, SetResAttrs will
do nothing and the ResError function will return the result code
resNotFound.


\ ChangedResource
1
PROCEDURE ChangedResource (theResource: Handle);

    Call ChangedResource after changing either the information about a
resource in the resource map (as described above under SetResInfo and
SetResAttrs) or the resource data for a resource, if you want the
change to be permanent. Given a handle to a resource, ChangedResource
sets the resChanged attribute for the resource. This attribute tells
the Resource Manager to do both of the following:

    - write the resource data for the resource to the resource file when
      the file is updated or when WriteResource is called

    - write the entire resource map to the resource file when the file
      is updated.

(warning)
    If you change information in the resource map with
    SetResénfo or SetResAttrs and then call ChangedResource,
    remember that not only the resource map but also the
    resource data will be written out when the resource file
    is updated.

    To change the resource data for a purgeable resource and make the
change permanent, you have to take special precautions to ensure that
the resource won't be purged while you're changing it. You can make
the resource temporarily unpurgeable and then write it out with
WriteResource before making it purgeable again. You have to use the
Memory Manager procedures  HNoPurge and HPurge to make the resource
unpurgeable and purgeable; SetResAttrs can't be used because it won't
take effect immediately. For example:

    myHndl := GetResource(type,ID;  {or LoadResource(myHndl) if  }
                    { you've gotten it previously}
    HNoPurge(myHndl);       {make it unpurgeable}
      . .  .          {make the changes here}
    ChangedResource(myHndl);    {mark it changed}
        WriteResource(myHndl);      {write it out}
    HPurge(myHndl)          {make it purgeable again}

    Or, instead of calling WriteResource to write the data out
immediately, you can call SetResPurge(TRUE) before making any changes to
purgeable resource data.

ChangedResource does nothing in the following cases:

    - The given handle isn't a handle to a resource. The ResError
      function will return the result code resNotFound.

    - Sufficient space for the modified resource file can't be reserved
      on the disk. ResError will return an appropriate Operating System
      result code.

(warning)
    Be aware that ChangedResource (and not WriteResource)
    checks to see if there's sufficient disk space to write
    out the modified file; it there isn't enough space, the 
    resChanged attribute won't be set. This means that when 
    Write Resource is called,it won't know that the resource
    file has been changed; it won't write out the modified
    file and no error will be returned. For this reason,
    always check to see that ChangedResource returns noErr.


\ AddResource
1
PROCEDURE AddResource (theData: Handle; theType: ResType; theID:
        INTEGER; name: Str255);

    Given a handle to data in memory (not a handle to an existing
resource), AddResource adds to the current resource file a resource
reference that points to the data. It sets the resChanged attribute
for the resource, so the data will be written to the resource file when
the file is updated or when WriteResource is called. If the given
handle is empty, zero-length resource data will be written.
AddResource does nothing in the following cases:

    - The given handle is NIL or is already a handle to an existing
      resource. The ResError function will return the result code
      addResFailed.

    - The resource map becomes too large to fit in memory or sufficient
      space for the modified resource file can't be reserved on the 
      disk. ResError will return an appropriate Operating System result
      code.

(warning)
    AddResource doesn't verify whether the resource ID you've
    passed is already assigned to another resource of the
    same type; be sure to call UniqueID before adding a
    resource.


\ RmveResource
1
PROCEDURE RmveResource (theResource: Handle);

    Given a handle to a resource in the current resource file,
RmveResource removes the resource reference to the resource. The
resource data will  be removed from the resource file when the file is
updated.

(note)
    RmveResource doesn't release the memory occupied by the 
    resource data; to do that, call the Memory Manager
    procedure DisposHandle after calling RmveResource.

    If the resProtected attribute for the resource is set or if the
given handle isn't a handle to a resource in the current resource file, 
Rmve Resource will do nothing and the ResError function will return the
result code rmvResFailed.


\ UpdateResFile
1
PROCEDURE UpdateResFile (refNum: INTEGER);

    Given the reference number of a resource file, UpdateResFile does
the following:

    - Changes, adds, or removes resource data in the file as appropriate
      to match the map. Remember that changed resource data is written
      out only if you called ChangedResource (and the call was
      successful); if you did, the resource data will be written out
      with WriteResource.

    - Compacts the resource file, closing up any empty space created
      when a resource was removed or made larger. (If the size of a
      changed resource is greater than its original size in the resource
      file, it's written at the end of the file rather than at its
      original location; the space occupied by the original is then
      compacted.)  UpdateResFile doesn't close up any empty space
      created when a resource is made smaller.

    - Writes out the resource map of the resource file, if you ever
      called ChangedResource for any resource in the file or if you
      added or removed a resource. All changes to resource information
      in the map will become permanent as a result of this, so if you
      want any such changes to be temporary, you must restore the
      original information before calling UpdateResFile.

    If there's no open resource file with the given reference number,
UpdateResFile will do nothing and the ResError function will return the
result code resFNotFound. A refNum of ¯ represent the system resource
file.

    The CloseResFile procedure calls UpdateResFile before it closes the
resource file, so you only need to call UpdateResFile yourself if you
want to update the file without closing it.


\ WriteResource
1
PROCEDURE WriteResource (theResource: Handle);

    Given a handle to a resource, WriteResource checks the resChanged
attribute for that resource and, if it's set (which it will be if you 
called ChangedResource or AddResource successfully), writes its
resource data to the resource file and clears its resChanged attribute.

(warning)
    Be aware that ChangedResource (and not WriteResource)
    determines if sufficient disk space is available to write
    out the modified file; if there isn't it will clear the 
    resChanged attribute and WriteResource will be unaware of
    the modifications. For this reason, always verify that
    ChangedResource returns noErr.

    If the resource is purgeable and has been purged, zero-length
resource data will be written. WriteResource does nothing if the
resProtected attribute for the resource is set or if the given handle
isn't a handle to a resource; in the latter case, the ResError function
will return the result code resNotFound.

    Since the resource file is updated when the application terminates
or when you call UpdateResFile (or CloseResFile, which calls
UpdateResFile), you only need to call WriteResource if you want to
write out just one or a few resources immediately.

(warning)
    The maximum size for resources to be written to a
    resource file is 32K bytes.


\ SetResPurge
1
PROCEDURE SetResPurge (install: BOOLEAN);

    SetResPurge(TRUE) sets a  "hook" in the Memory Manager such that
before purging data specified by a handle,the Memory Manager will first
pass the handle to the Resource Manager. The Resource Manager will
determine whether the handle is that of a resource in the application
heap and, if so, will call WriteResource to write the resource data for
that resource to the resource file if its resChanged attribute is set
(see ChangedResource and WriteResource above). SetResPurge(FALSE)
restores the normal state, clearing the hook so that the Memory Manager
will once again purge without checking with the Resource Manager.

    SetResPurge(TRUE) is useful in applications that modify purgeable
resources. You still have to make the resources temporarily
unpurgeable while making the changes, as shown in the description of
ChangedResource, but you can set the purge hook instead of writing the
data out immediately with WriteResource. Notice that you won't know 
exactly when the resources are being written out; most applications
will want more control than this. If you wish, you can set your own
such hook; for details, refer to the section "Memory Manager Data
Structures" in the Memory Manager manual.


\ GetResFileAttrs
1
FUNCTION GetResFileAttrs (refNum: INTEGER) : INTEGER;

    Given the reference number of a resource file, GetResFileAttrs
returns the resource file attributes for the file. If there's no
resource file with the given reference number, GetResFileAttrs will do
nothing and the ResError function will return the result code
resFNotFound. A refNum of ¯ represents the system resource file.


\ SetResFileAttrs
1
PROCEDURE SetResFileAttrs (refNum: INTEGER; attrs: INTEGER);

    Given the reference number of a resource file, SetResFileAttrs sets
the  resource file attributes of the file to attrs. If there's no
resource file with the given reference number, SetResFileAttrs will do
nothing and the ResError function will return the result code
resFNotFound. A refNum of  ¯ represents the system resource file, but
you shouldn't change its resource file attributes.


\ AddReference
1
PROCEDURE AddReference (theResource: Handle; theID: INTEGER; name:
      Str255);

    Given a handle to a system resource, AddReference adds to the
current resource file a system reference to the resource, giving it the
ID number and name specified by the parameters. It sets the resChanged
attribute for the resource, so the reference will be written to the
resource file when the file is updated. AddReference does nothing in
the following cases:

    - The current resource file is the system resource file or already
      contains a system reference to the specified resource, or the
      given handle isn't a handle to a system resource. The ResError
      function will return the result code.

        CONST addReFailed = -195;  (AddReference failed)

    - The resource map becomes too large to fit in the memory or
      sufficient space for the modified resource file can't be
      reserved on the disk. ResError will return an appropriate
      ¯perating System result code.


\ RmveReference
1
PROCEDURE RmveReference (theResource: Handle);

    Given a handle to a system resource, RmveReference removes the
system reference to the resource from the current resource file. (The
reference will be removed from the resource file when the file is
updated.)  RmveReference will do nothing and the ResError function will
return the result code.

        CONST rmvRefFailed = -197;  (RmveReference failed)

if any of the following are true:

    - The resProtected attribute for the resource is set.

    - There's no system reference to the resource in the current 
      resource file.

    - The given handle isn't a handle to a system resource. 

\ Count1Types
1
FUNCTION Count1Types : INTEGER;

    Count1Types is the same as CountTypes except that it returns the
number of resource types in the current resource file only.

\ Get1IndType
1
PROCEDURE Get1IndType (VAR theType: ResType; index: INTEGER);
___________________________________________________________________

Assembly-language note:  The macro you invoke to call Get1IndType
from assembly language is named _Get1IxType.
___________________________________________________________________
    Get1IndType is the same as GetIndType except that it searches the
current resource file only. Given an index ranging from 1 to
Count1Types (above), Get1IndType returns a resource type in theType.

    Called repeatedly over the entire range for the index, it returns
all the resource types in the current resource file. If the given
index isnÕt in the range from 1 to Count1Types, Get1IndType returns
four NUL characters (ASCII code 0).

\ Count1Resources
1
FUNCTION Count1Resources (theType: ResType) : INTEGER;

    Count1Resources is the same as CountResources except that it returns
the total number of resources of the given type in the current resource
file only.

\ Get1IndResource
1
FUNCTION Get1IndResource (theType: ResType; index: INTEGER) : Handle;
___________________________________________________________________

Assembly-language note:  The macro you invoke to call
Get1IndResource from assembly language is named _Get1IxResource.
___________________________________________________________________
    Get1IndResource is the same as GetIndResource except that it
searches the current resource file only. Given an index ranging from 1
to Count1Resources(theType), Get1IndResource returns a handle to a
resource of the given type (see Count1Resources, above). Called
repeatedly over the entire range for the index, it returns handles to
all resources of the given type in the current resource file.

\ Get1Resource
1
FUNCTION Get1Resource (theType: ResType; theID: INTEGER) : Handle;

    Get1Resource is the same as GetResource except that it searches the
current resource file only.

\ Get1NamedResource
1
FUNCTION Get1NamedResource (theType: ResType; name: Str255) : Handle;

    Get1NamedResource is the same as GetNamedResource except that it
searches the current resource file only.

\ Unique1ID
1
FUNCTION Unique1ID (theType: ResType) : INTEGER;

    Unique1ID is the same as UniqueID except that the ID number it
returns is unique only with respect to resources in the current resource
file.

\ MaxSizeRsrc
1
FUNCTION MaxSizeRsrc (theResource: Handle) : LONGINT;

    MaxSizeRsrc is similar to SizeResource except that it does not cause
the disk to be read; instead it determines the size (in bytes) of
the resource from the offsets found in the resource map.

    Since MaxSizeRsrc does not read from the disk, it returns only the
maximum size of the resource. In other words, you can count on the
resource not being larger than the number of bytes reported by
MaxSizeRsrc; itÕs possible, however, that the resource is actually
smaller than the resource map indicates (because the file has not
yet been compacted). If called after UpdateResFile, MaxSizeRsrc will
return the correct size of the resource.

\ RsrcMapEntry
1
FUNCTION RsrcMapEntry (theResource: Handle) : LONGINT;

    RsrcMapEntry  provides a way to access the resource references in
the resource map. Given a handle to a resource, RsrcMapEntry returns
the offset of the resourceÕs reference from the beginning of the
resource map. (For more information on resource references and the
structure of a resource map, see the section ŌFormat of a Resource FileĶ
in the Resource Manager chapter.)  If it doesnÕt find the resource,
RsrcMapEntry returns NIL and the ResError function will return the
result code resNotFound. If you pass it a NIL handle, RsrcMapEntry
will return garbage but ResError will return the result code noErr.

Warning:  Since routines are provided for opening, accessing,
          and changing resources, thereÕs really no reason to access
          resources directly. To avoid damaging the resource file, you
          should be extremely careful if you use RsrcMapEntry.


\ OpenRFPerm
1
FUNCTION OpenRFPerm (fileName: Str255; vRefNum: INTEGER; permission: Byte) : INTEGER;

    OpenRFPerm is similar to OpenResFile except that it allows you to
specify the read/write permission of the resource file the first time
it is opened; OpenRFPerm also lets you specify in vRefNum the directory
or volume on which the file is located (see chapter 19 of this volume
for more details on directories). Permission can have any of the values
that you would pass to the File Manager; these values are given
in ŌLow-Level File Manager RoutinesĶ in chapter 19 of this volume.

    OpenRFPerm, like OpenResFile, will not open the specified file twice
it simply returns the reference number already assigned to the file.
In other words, OpenRFPerm cannot be used to open a second access
path to a resource file nor can it be used to change the permission
of an already open file. Since OpenRFPerm gives no indication of
whether the file was already open, thereÕs no way to tell whether
the fileÕs open permission is what you specified or what was
specified by an earlier call.

Note:  The shared read/write permission described in chapter 19
of this volume has no effect with OpenRFPerm since the Resource
Manager is unable to deal with a portion of a resource file.

\ InitGraf
2
PROCEDURE InitGraf (globalPtr: QDPtr);

    Call InitGraf once and only once at the beginning of your program
to initialize QuickDraw. It initializes the QuickDraw global variables
listed below.

    Variable    Type        Initial Setting
    -----------------------------------------------

    thePort     GrafPtr     NIL
    white       Pattern     all-white pattern
    black       Pattern     all-black pattern
    gray        Pattern     50% gray pattern
    ltGray      Pattern     25% gray pattern
    dkGray      Pattern     75% gray pattern
    arrow       Cursor      pointing arrow cursor
    screenBits  BitMap      Macintosh screen, (¯,¯,512,342)
    randSeed    LongInt     1

    The globalPtr parameter tells QuickDraw where to store its global
variables, beginning with thePort. From Pascal programs, this
parameter should always be set to @the Port; assembly-language
programmers may choose any location, as long as it can accommodate the
number of bytes specified by GRAFSIZE in GRAFTYPES.TEXT (see "Using 
QuickDraw from Assembly Language").

(hand)
    To initialize the cursor, call InitCursor (described
    under "Cursor Handling Routines" below).

\ OpenPort
2
PROCEDURE OpenPort (gp: GrafPtr);

    OpenPort allocates space for the given grafPort's visRgn and clipRgn 
initializes the fields of the frafPort as indicated below, and makes
the grafPort the current port (see SetPort). You must call OpenPort
before using any graf¸ort; first perform a NEW to create a grafPtr and
then use  that graf¸tr in the OpenPort call.

    Field       Type        Initial Setting

    device      INTEGER     ¯ (Macintosh screen)
    portBits    BitMap      screenBits (see InitGraf)
    portRect    Rect        screenBits.bounds (¯,¯,512,342)
    visRgn      RgnHandle   handle to the rectangular region
                            (¯,¯,512,342)
    clipRgn     RgnHandle   handle to the rectangular region
                            (-3¯¯¯¯,-3¯¯¯¯,3¯¯¯¯,3¯¯¯¯)
    bkPat       Pattern     white
    fillPat     Pattern     black
    pnLoc       Point       (¯,¯)
    pnSize      Point       (1,1)
    pnMode      INTEGER     patCopy
    pnPat       Pattern     black
    pnVis       INTEGER     ¯ (visible)
    txFont      INTEGER     ¯ (system font)
    txFace      Style       normal
    txMode      INTEGER     srcOr
    txSize      INTEGER     ¯ (Font Manager decides)
    spExtra     INTEGER     ¯
    fgColor     LongInt     blackColor
    bkColor     LongInt     whiteColor
    colrBit     INTEGER     ¯
    patStretch  INTEGER     ¯
    picSave     QDHandle    NIL
    rgnSave     QDHandle    NIL
    polySave    QDHandle    NIL
    grafProcs   QDProcsPtr  Nil


\ InitPort
2
PROCEDURE InitPort (gp: GrafPtr);

    Given a pointer to a grafPort that has been opened with OpenPort,
InitPort reinitializes the fields of the grafPort and makes it the
current port (if it's not already).

(hand)
    InitPort does everything OpenPort does except allocate
    space for the visRgn and clipRgn.


\ ClosePort
2
PROCEDURE ClosePort (gp: GrafPtr)

    ClosePort deallocates the space occupied by the given GrafPort's
visRgn and clipRgn. When you are completely through with a grafPort,
call this procedure and then dispose of the grafPort (with a DISPOSE of
the grafPtr).

(eye)
    If you do not call ClosePort before disposing of the
    grafPort, the memory used by the visRgn and clipRgn will
    be unrecoverable.

(eye)
    After calling ClosePort, be sure not use any copies of
    the visRgn or clipRgn handles that you may have made.


\ SetPort
2
PROCEDURE SetPort (gp: GrafPtr);

    SetPort sets the grafPort indicated by gp to be the current port.
The global pointer thePort always points to the current port. All
QuickDraw drawing routines affect the bitMap thePort^.portBits and use
the local coordinate system of thePort^. Note that OpenPort and
InitPort do a SetPort to the given port.

(eye)
    Never do a SetPort to a port that has not been opened
    with OpenPort.

    Each port possesses its own pen and text characteristics which
remain unchanged when the port is not selected as the current port.


\ GetPort
2
PROCEDURE GetPort (VAR gp: GrafPtr);

    GetPort returns a pointer to the current grafPort. If you have a
program that draws into more than one grafPort, it's extremely useful 
to have each procedure save the current grafPort (with GetPort), set
its own grafPort, do drawing or calculations, and then restore the
previous grafPort (with SetPort). The pointer to the current grafPort
is also available through the global pointer thePort, but you may
prefer to use GetPort for better readability of your program text. For
example, a procedure could do a GetPort (savePort) before setting its
own grafPort and a SetPort (savePort) afterwards to restore the
previous port.


\ GrafDevice
2
PROCEDURE GrafDevice (device: INTEGER);

    GrafDevice sets thePort^.device to the given number, which
identifies the logical output device for this grafPort. The Font
Manager uses this information. The initial device number is ¯, which
represents the Macintosh screen.

\ SetPortBits
2
PROCEDURE SetPortBits (bm: BitMap);

    SetPortBits sets the Port^.portBits to any previously defined
bitMap. This allows you to perform all normal drawing and calculations
on a buffer other than the Macintosh screen -- for example, a 64¯-by-7
output buffer for a C. Itoh printer, or a small off-screen image for
later "stamping" onto the screen.

    Remember to prepare all fields of the bitMap before you call
SetPortBits.


\ PortSize
2
PROCEDURE PortSize (width, height:  INTEGER);

    PortSize changes the size of the current grafPort's portRect. THIS 
DOES NOT AFFECT THE SCREEN; it merely changes the size of the "active
area" of the grafPort. 

(hand)
    This procedure is normally called only by the Window
    Manager.

    The top left corner of the portRect remains at its same location;
the width and height of the portRect are set to the given width and
height. In other words, PortSize moves the bottom right corner of the
portRect to a position relative to the top left corner.

    PortSize does not change the clipRgn or the visRgn, nor does it
affect the local coordinate system of the grafPort: it changes only the
portRect's width and height. Remember that all drawing occurs only in 
the intersection of the portBits.bounds  and the portRect, clipped to
the visRgn and the clipRgn.


\ MovePortTo
2
PROCEDURE MovePortTo (leftGlobal,topGlobal: INTEGER);

    MovePortTo changes the position of the current grafPort's portRect.
THIS DOES NOT AFFECT THE SCREEN; it merely changes the location at
which subsequent drawing inside the port will appear.

(hand)
    This procedure is normally called only by the Window
    Manager.

    The leftGlobal and topGlobal parameters set the distance between the
top left corner of portBits.bounds and the top left corner of the new
portRect. For example,

    MovePortTo(256,171);

will move the top left corner of the portRect to the center of the
screen (if portBits is the Macintosh screen) regardless of the local
coordinate system.

Like PortSize, MovePortTo does not change the clipRgn or the visRgn,
nor does it affect the local coordinate system of the grafPort.


\ SetOrigin
2
PROCEDURE SetOrigin (h,v: INTEGER);

    SetOrigin changes the local coordinate system of the current
grafPort. THIS DOES NOT AFFECT THE SCREEN; it does, however, affect
where subsequent drawing and calculation will appear in the grafPort.
SetOrigin updates the coordinates of the portBits.bounds, the portRect,
and the visRgn. All subsequent drawing and calculation routines will
use the new coordinate system.

    The h and v parameters set the coordinates of the top left corner of
the portRect. All other coordinates are calculated from this point.
All relative distances among any elements in the port will remain the
same; only their absolute local coordinates will change.

(hand)
    SetOrigin does not update the coordinates of the clipRgn
    or the pen; these items stick to the coordinate system
    (unlike the port's structure, which sticks to the 
    screen).

    SetOrigin is useful for adjusting the coordinate system after a
scrolling operation. (See ScrollRect under "Bit Transfer Operations"
below.)


\ SetClip
2
PROCEDURE SetClip (rgn: RgnHandle);

    SetClip changes the clipping region of the current grafPort to a
region equivalent to the given region. Note that this does not change
the region handle, but affects the clipping region itself. Since SetClip
makes a copy of the given region, any subsequent changes you make to
makes a copy of the given region, any subsequent changes you make to
that region will not affect the clipping region of the port.

    You can set the clipping region to any arbitrary region, to aid you
in drawing inside the grafPort. The initial clipRgn is an arbitrarily
large rectangle.


\ GetClip
2
PROCEDURE GetClip (rgn: RgnHandle);

    GetClip changes the given region to a region equivalent to the
clipping region of the current grafPort. This is the reverse of what
SetClip does. Like SetClip, it does not change the region handle.


\ ClipRect
2
PROCEDURE ClipRect (r: Rect);

    ClipRect changes the clipping region of the current grafPort to a
rectanble equivalent to given rectangle. Note that this does not
change the region handle, but affects the region itself.


\ BackPat
2
PROCEDURE BackPat (pat: Pattern);

    BackPat sets the background pattern of the current grafPort to the
given pattern. The background pattern is used in ScrollRect and in all
QuickDraw routines that perform an "erase" operation.




\ InitCursor
2
PROCEDURE InitCursor;

    InitCursor sets the current cursor to the predefined arrow cursor,
an arrow pointing north-northwest, and sets the CURSOR LEVEL to ¯,
making the cursor visible. The cursor level, which is initialized to ¯
when the system is booted, keeps track of the number of times the cursor
has been hidden to compensate for nested calls to HideCursor and
ShowCursor (below).

    Before you call InitCursor, the cursor is undefined (or, if set by a
previous process, it's whatever that process set it to).


\ SetCursor
2
PROCEDURE SetCursor (crsr: Cursor);

    SetCursor sets the current cursor to the 16-by-16-bit image in crsr.
If the cursor is hidden, it remains hidden and will attain the new
appearnce when it's uncovered; if the cursor is already visible, it
changes to the new appearance immediately.

    The cursor image is initialized by InitCursor to a north-northwest
arrow, visible on the screen. There is no way to retrieve the current
cursor image.

\ HideCursor
2
PROCEDURE HideCursor;

    HideCursor removes the cursor from the screen, restoring the bits
under it, and decrements the cursor level (which InitCursor initialized
to ¯). Every call to HideCursor should be balanced by a subsequent call
to ShowCursor.


\ ShowCursor
2
PROCEDURE ShowCursor;

    ShowCursor increments the cursor level, which may have been
decremented by HideCursor, and displays the cursor on the screen if the
level becomes ¯. A call to ShowCursor should balance each previous call
to HideCursor. The level is not incremented beyond ¯, so extra calls to
ShowCursor don't hurt.

    QuickDraw low-level interrupt-driven routines link the cursor with
the mouse position, so that if the cursor level is ¯ (visible), the
cursor automatically follows the mouse. You don't need to do anything
but a ShowCursor to have a cursor track the mouse. There is  no way to
"disconnect" the cursor from the mouse; you can't force the cursor to a 
certain position, nor can you easily prevent the cursor from entering a
certain area of the screen.

    If the cursor has been changed (with SetCursor) while hidden,
ShowCursor presents the new cursor.

    The cursor is initialized by InitCursor to a north-northwest arrow,
not hidden.


\ ObscureCursor
2
PROCEDURE ObscureCursor;

    ObscureCursor hides the cursor until the next time the mouse is
moved. Unlike HideCursor, it has no effect on the cursor level and must
not be balanced by a call to ShowCursor.

\ HidePen
2
PROCEDURE HidePen

    HidePen decrements the current grafPort's pnVis field, which is 
initialized to ¯ by OpenPort; whenever pnVis is negative, the pen does
not draw on the screen. PnVis keeps track of the number of times the
pen has been hidden to compensate for nested calls to HidePen and
ShowPen (below). HidePen is called by OpenRgn, OpenPicture, and
OpenPoly so that you can define regions, pictures, and polygons without
drawing on the screen.

\ ShowPen
2
PROCEDURE ShowPen;

    ShowPen increment the current grafPort's pnVis field, which may have
been decremented by HidePen; if pnVis becomes ¯, QuickDraw resumes
drawing on the screen. Extra calls to ShowPen will increment pnVis
beyond ¯, so every call to ShowPen should be balanced by a subsequent
call to HidePen. ShowPen is called by CloseRgn, ClosePicture, and
ClosePoly.
\ GetPen
2
PROCEDURE GetPen (VAR pt: Point);

    GetPen returns the current pen location, in the local coordinates of
the current grafPort.
\ GetPenState
2
PROCEDURE GetPenState (VAR pnState: PenState);

    GetPenState saves the pen location, size, pattern, and mode into a
storage variable, to be restored later with SetPenState (below). This
is useful when calling short subroutines that operate in the current
port but must change the graphics pen: each such procedure can save
the pen's state when it's called, do whatever it needs to do, and
restore the previous pen state immediately before returning.

    The PenState data type is not useful for anything except saving the
pen's state.
\ SetPenState
2
PROCEDURE SetPenState (pnState: PenState);

    SetPenState sets the pen location, size, pattern, and mode in the
current grafPort to the values stored in pnState. This is usually
called at the end of a procedure that has altered the pen parameters
and wants to restore them to their state at the beginning of the
procedure. (See GetPenState, above.)
\ PenSize
2
PROCEDURE PenSize (width, height: INTEGER);

    PenSize sets the dimensions of the graphics pen in the current
grafPort. All subsequent calls to Line, LineTo, and the procedures
that draw framed shapes in the current grafPort will use the new pen
dimensions.

    The pen dimensions can be accessed in the variable thePort^.pnSize,
which is of type Point. If either of the pen dimensions is set to a
negative value, the pen assumes the dimensions (¯,¯) and no drawing is
performed. For a discussion of how the pen draws, see the "General 
Discussion of Drawing" earlier in this manuel.
\ PenMode
2
PROCEDURE PenMode (mode: INTEGER);

    PenMode sets the transfer mode through which the pnPat is
transferred onto the bitMap when lines or shapes are drawn. The mode
may be any one of the pattern transfer modes:

    patCopy     patXor      notPatCopy  notPatXor
    patOr       patBic      notPatOr    notPatBic

    If the mode is one of the source transfer modes (or negative), no
drawing is performed. The current pen mode can be obtained in the
variable thePort^.pnMode. The initial pen mode is patCopy, in which
the pen pattern is copied directly to the bitMap.
\ PenPat
2
PROCEDURE PenPat (pat: Pattern);

    PenPat sets the pattern that is used by the pen in the current
grafPort. The standard patterns white, black, gray, ltGray and dkGray
are predefined; the initial pnPat is black. The current pen pattern
can be obtained in the variable thePort^.onPat, and this value can be
assigned (but not compared!) to any other variable of type Pattern.
\ PenNormal
2
PROCEDURE PenNormal;

    PenNormal resets the initial state of the pen in the current
grafPort, as follows:

    Field       Setting
    -----           -------
    pnSize      (1,1)
    pnMode      patCopy
    pnPat       black

    The pen location is not changed.
\ MoveTo
2
PROCEDURE MoveTo (h,v: INTEGER);

    MoveTo moves the pen to location  (h,v) in the local coordinates of
the current grafPort. No drawing is performed.
\ Move
2
PROCEDURE Move (dh,dv: INTEGER);

    This procedure moves the pen a distance of dh horizontally and dv
vertically from its current location; it calls MoveTo(h+dh,v+dv), where
(h,v) is the current location,  The positive directions are to the
right and down. No drawing is performed.
\ LineTo
2
PROCEDURE LineTo (h,v: INTEGER);

    LineTo draws a line from the current pen location to the location
specified (in local coordinates) by h and v. The new pen location is
(h,v) after the line is drawn. See the general discussion of drawing.

    If a region or polygon is open and being formed, its outline is
infinitely thin and is not affected by the pnSize, pnMode, or pnPat.
(See OpenRgn and OpenPoly.)
\ Line
2
PROCEDURE Line (dh,dv: INTEGER);

    This procedure draws a line to the location that is a distance of dh
horizontally and dv vertically from the current pen location; it calls
LineTo(h+dh,v+dv), where (h,v) is the current location. The positive
directions are to the right and down. The pen location becomes the
coordinates of the end of the line after the line is drawn. See the
general discussion of drawing.

    If a region or polygon is open and being formed, its outline is
infinitely thin and is not affected by the pnSize, pnMode, or pnPat.
(See OpenRgn and OpenPoly.)
\ TextFont
2
PROCEDURE TextFont (font:INTEGER);

    TextFont sets the current grafPort's font (thePort^.txFont) to the 
given font number. The initial font number is ¯, which represents the
system font.
\ TextFace
2
PROCEDURE TextFace (face:Style);

    TextFace sets the current grafPort's character style
(thePort^.txFace). The Style data type allows you to specify a set of
one or more of the following predefined constants: bold, italic,
underline, outline, shadow, condense, and extend. For example:

    TextFace([bold])                    {bold}
    TextFace([bold,italic]);            {bold and italic}
    TextFact(thePort^.txFace+[bold]);   {whatever it was plus bold}
    TextFace(thePort^.txFace-[bold]);   {whatever it was but not bold}
    TextFace([]);                       {normal}
\ TextMode
2
PROCEDURE TextMode (mode: INTEGER);

    TextMode sets the current grafPort's transfer mode for drawing text
(thePort^.txMode). The mode should be srcOr, srcXor, or srcBic. The
initial transfer mode for drawing text is srcOR.
\ TextSize
2
PROCEDURE TextSize (size: INTEGER);

    TextSize sets the current grafPort's type size (thePort^.txSize) to
the given number of points. Any size may be specified, but the result
will look best if the Font Manager has the font in that size (otherwise
it will scale a size it does have). The next best result will occur if
the given state is an even multiple of a size available for the font.
If ¯ is specified, the Font Manager will choose one of the available
sizes -- whichever is closest to the system font size. The initial
txSize setting is ¯.
\ SpaceExtra
2
PROCEDURE SpaceExtra (extra: INTEGER);

    SpaceExtra sets the current grafPort's spExtra field, which
specifies the number of pixels by which to widen each space in a line of
text. This is useful when text is being fully justified (that is,
aligned with both a left and a right margin). Consider, for example, a
line that contains three spaces; if there would normally be six pixels
between the end of the line and the right margin, you would call
SpaceExtra(2) to print the line with full justification. The initial
spExtra setting is ¯.

(hand)
    Space Extra will also take a negative argument, but be
    careful not to narrow spaces so much that the text is
    unreadabe.


\ DrawChar
2
PROCEDURE DrawChar (ch: CHAR);

    DrawChar places the given character to the right of the pen
location, with the left end of its base line at the pen's location, and
advances the pen accordingly. If the character is not in the font, the
font's  missing symbol is drawn.
\ DrawString
2
PROCEDURE DrawString (s: Str255);

    DrawString performs consecutive calls to DrawChar for each character
in the supplied string; the string is placed beginning at the current
pen location and extending right. No formatting (carriage returns, line
feeds, etc.)  is performed by QuickDraw. The pen location ends up to
the right of the last character in the string.
\ DrawText
2
PROCEDURE DrawText (textBuf: QDPtr; firstByte,byteCount: INTEGER);

    DrawText draws text from an arbitrary structure in memory specified
by textBuf, starting first Byte bytes into the structure and continuing
for byteCount bytes. The string of text is placed beginning at the
current pen location and extending right. No formatting (carriage
returns, line feeds, etc.) is performed by QuickDraw. The pen location
ends up to the right of the last character in the string.
\ CharWidth
2
FUNCTION CharWidth (ch: CHAR) : INTEGER;

    CharWidth returns the value that will be added to the pen horizontal
coordinate if the specified character is drawn. CharWidth includes the
effects of the stylistic variations set with TextFace; if you change
these after determining the character width but before actually drawing
the character, the  predetermined width may not be correct. If the
character is a space, CharWidth also includes the effect of SpaceExtra.
\ StringWidth
2
FUNCTION StringWidth (s: Str255 ) : INTEGER;

    StringWidth returns the width of the given text string, which it
calculates by adding the CharWidths of all the characters in the string
(see above). This value will be added to the pen horizontal coordinate
if the specified string is drawn.
\ TextWidth
2
FUNCTION TextWidth (textBuf: QDPtr; firstByte,byteCount: INTEGER) :
    INTEGER;

    TextWidth returns the width of the text stored in the arbitrary
structure in memory specified by textBuf, starting firstByte bytes into
the structure and continuing for byteCount bytes. It calculates the
width by adding the CharWidths of all the characters in the text. (See
CharWidth, above.)
\ GetFontInfo
2
PROCEDURE GetFontInfo (VAR into: FontInfo);

    GetFontInfo returns the following information about the current
grafPort's character font, taking into consideration the style and size 
in which the characters will be drawn:  the ascent, descent, maximum
character width (the greatest distance the pen will move when a
character is drawn), and leading (the vertical distance between the
descent line and the ascent line below it), all in pixels. The
FontInfo data structure is defined as:

    TYPE FontInfo = RECORD
            ascent:  INTEGER;
            descent: INTEGER;
            widMax:  INTEGER;
            leading: INTEGER;
          END;
\ Forecolor
2
PROCEDURE ForeColor (color: LongInt);

    ForeColor sets the foreground color for all drawing in the current
grafPort (^thePort.fgColor) to the given color. The following standard
colors are predefined:  blackColor, whiteColor, redColor, greenColor,
blueColor, cyanColor, magentaColor, and yellowColor. The initial
foreground color is blackColor.
\ BackColor
2
PROCEDURE BackColor (color: LongInt)

    BackColor sets the background color for all drawing in the current
grafPort (^thePort.bkColor) to the given color.  Eight standard colors
are predefined (see ForeColor above). The initial background color is
whiteColor.
\ ColorBit
2
PROCEDURE ColorBit (whichBit: INTEGER);

    ColorBit is called by printing software for a color printer, or
other color-imaging software, to set the current grafPort's colrBit
field to whichBit; this tells QuickDraw which plane of the color picture
to draw into. QuickDraw will draw into the plane corresponding to bit
number whichBit. Since QuickDraw can support output devices that have
up to 32 bits of color information per pixel, the possible range of
values for whichBit is ¯ through 31. The initial value of the colrBit
field is ¯.
\ SetRect
2
PROCEDURE SetRect (VAR r: Rect; left,top,right, bottom; INTEGER);

    SetRect assigns the four boundary coordinates to the rectangle. The
result is a rectangle with coordinates (left,top,right,bottom).

    This procedure is supplied as a utility to help you shorten your
program text. If you want a more readable text at the expense of
length, you can assign integers (or points) directly into the
rectangle's fields. There is no significant code size or execution 
speed advantage to either method; one's just easier to write, and the 
other's easier to read.
\ OffSetRect
2
PROCEDURE OffsetRect (VAR r: Rect; dh,dv: INTEGER);

    OffsetRect moves the rectangle by adding dh to each horizontal
coordinate and dv to each vertical coordinate. If dh and dv are
positive, the movement is to the right and down; if either is negative,
the corresponding movement is in the opposite direction. The rectangle
retains its shape and size; it's merely moved on the coordinate plane. 
This does not affect the screen unless you subsequently call a routine
to draw within the rectangle.
\ InsetRect
2
PROCEDURE InsetRect (VAR r: Rect; dh,dv: INTEGER);

    InsetRect shrinks or expands the rectangle. The left and right
sides are moved in by the amount specified by dh; the top and bottom are
moved towards the center by the amount specified by dv. If dh or dv is
negative, the appropriate pair of sides is moved outwards instead of
inwards.  The effect is to alter the size by 2*dh horizontally and 2*dv
vertically, with the rectangle remaining centered in the same place on
the coordinate plane.

    If the resulting width or height becomes less than 1, the rectangle
is set to the empty rectangle (¯,¯,¯,¯).
\ SectRect
2
FUNCTION SectRect(srcRectA,srcRectB: Rect; VAR dstRect: Rect) :
    BOOLEAN;

    SectRect calculates the rectangle that is the intersection of the
two input rectangles, and returns TRUE if they indeed intersect or FALSE
if they do not. Rectangles that "touch" at a line or a point are not
considered intersecting, because their intersection rectangle (really,
in this case, an intersection line or point) does not enclose any bits
on the bitMap.

    If the rectangles do not intersect, the destination rectangle is set
to (¯,¯,¯,¯,). SectRect works correctly even if one of the source
rectangles is also the destination.
\ UnionRect
2
PROCEDURE UnionRect (srcRectA,srcRectB: Rect; VAR dstRect: Rect);

    Union Rect calculates the smallest rectangle which encloses both
input rectangles. It works correctly even if one of the source
rectangles is also the destination.
\ PtInRect
2
FUNCTION PtInRect (pt: Point; r: Rect) : BOOLEAN;

    PtInRect determines whether the pixel below and to the right of the
given coordinate point is enclosed in the specified rectangle, and
returns TRUE if so or FALSE if not.
\ Pt2Rect
2
PROCEDURE Pt2Rect (ptA,ptB: Point; VAR: dstRect: Rect);

    Pt2Rect returns the smallest rectangle which encloses the two input
points.
\ PtToAngle
2
PROCEDURE PtToAngle (r: Rect; pt: Point; VAR angle: INTEGER);

    PtToAngle calculates an integer angle between a line from the center
of the rectangle to the given point and a line from the center of the
rectangle pointing straight up (12 o'clock high). The angle is in 
degrees from ¯ to 359, measured clockwise from 12 o'clock, with 9¯
degrees at 3 o'clock, 18¯ at 6o'clock, and 27¯ at 9 o'clock. Other
angles are measured relative to the rectangle: if the line to the
given point goes through the top right corner of the rectangle, the
angle returned is 45 degrees, even if the rectangle is not square; if
it goes through the bottom right corner, the angle is 135 degrees, and
so on (see Figure 18).

    The angle returned might be used as input to one of the procedures
that manipulate arcs and wedges, as described below under "Graphic 
Operations on Arcs and Wedges".
\ EqualRect
2
FUNCTION EqualRect (rectA,rectB: Rect) : BOOLEAN;

    EqualRect compares the two rectangles and returns TRUE if they are
equal or FALSE if not. The two rectangles must have identical boundary
coordinates to be considered equal.


\ EmptyRect
2
FUNCTION EmptyRect (r: Rect) : BOOLEAN;

    EmptyRect returns TRUE if the given rectangle is an empty rectangle
or FALSE if not. A rectangle is considered empty if the bottom
coordinate is equal to or less than the top or the right coordinate is
equal to or less than the left.
\ FrameRect
2
PROCEDURE FrameRect (r: Rect);

    FrameRect draws a hollow outline just inside the specified rectangle
using the current grafPort's pen pattern, mode, and size. The outline 
is as wide as the pen width and as tall as the pen height. It is drawn
with the pnPat, according to the pattern transfer mode specified by
pnMode. The pen location is not changed by this procedure.

    If a region is open and being formed, the outside outline of the new
rectangle is mathematically added to the region's boundary.
\ PaintRect
2
PROCEDURE PaintRect (r: Rect);

    PaintRect paints the specified rectangle with the current grafPort's 
pen pattern and mode. The rectangle on the bitMap is filled with the
pnPat, according to the pattern transfer mode specified by pnMode. The
pen location is not changed by this procedure.
\ EraseRect
2
PROCEDURE EraseRect (r: Rect);

    EraseRect paints the specified rectangle with the current grafPort's 
background pattern bkPat (in patCopy mode). The grafPort's pnPat and 
pnMode are ignored; the pen location is not changed.
\ InvertRect
2
PROCEDURE InvertRect (r: Rect);

				__________________________________________________________________
					 Assembly-Language note: The macro you invoke to call InvertRect
						from  assembly language is named _InverRect.
				__________________________________________________________________

    InvertRect inverts the pixels enclosed by the specified rectangle:
every white pixel becomes black and every black pixel becomes white.
The grafPort's pnPat, pnMode, and bkPat are all ignored; the pen 
location is not changed.
\ FillRect
2
PROCEDURE FillRect (r: Rect; pat: Pattern);

    FillRect fills the specified rectangle with the given pattern (in
patCopy mode). The grafPort's pnPat, pnMode, and bkPat are all 
ignored; the pen location is not changed.
\ FrameOval
2
PROCEDURE FrameOval (r: Rect);

    FrameOval draws a hollow outline just inside the oval that fits
inside the specified rectangle, using the current grafPort's pen
pattern, mode, and size. The outline is as wide as the pen width and as
tall as the pen height. It is drawn with the pnPat, according to the
pattern transfer mode specified by pnMode. The pen location is not
changed by this procedure.

    If a region is open and being formed, the outside outline of the new
oval is mathematically added to the region's boundary.
\ PaintOval
2
PROCEDURE PaintOval (r: Rect);

    PaintOval paints an oval just inside the specified rectangle with
the current grafPort's pen pattern and mode. The oval on the bitMap is 
filled with the pnPat, according to the pattern transfer mode specified
by pnMode. The pen location is not changed by this procedure.
\ EraseOval
2
PROCEDURE EraseOval (r: Rect);

    EraseOval paints an oval just inside the specified rectangle with
the current grafPort's background pattern bkPat (in patCopy mode). The 
grafPort's pnPat and pnMode are ignored; the pen location is not  
changed.
\ InvertOval
2
PROCEDURE InvertOval (r: Rect);

    InvertOval inverts the pixels enclosed by an oval just inside the
specified rectangle: every white pixel becomes black and every black
pixel becomes white. The grafPort's pnPat, pnMode, and bkPat are all 
ignored; the pen location is not changed.
\ FillOval
2
PROCEDURE FillOval (r: Rect; pat: Pattern);

    FillOval fills an oval just inside the specified rectangle with the
given pattern in patCopy mode). The grafPort's pnPat, pnMode, and 
bkPat are all ignored; the pen location is not changed.
\ FrameRoundRect
2
PROCEDURE FrameRoundRect (r: Rect; ovalWidth,ovalHeight: INTEGER);

    FrameRoundRect draws a hollow outline just inside the specified
rounded-corner rectangle, using the current grafPort's pen pattern, 
mode, and size. OvalWidth and ovalHeight specify the diameters of
curvature for the corners (see Figure 19). The outline is as wide as
the pen width and as tall as the pen height. It is drawn with the
pnPat, according to the pattern transfer mode specified by pnMode. The
pen location is not changed by this procedure.

    If a region is open and being formed, the outside outline of the new
rounded-corner rectangle is mathematically added to the region's 
boundary.
\ PaintRoundRect
2
PROCEDURE PaintRoundRect (r: Rect; ovalWidth,ovalHeight: INTEGER);

    PaintRoundREct paints the specified rounded-corner rectangle with
the current grafPort's pen pattern and mode. OvalWidth and ovalHeight
specify the diameters of curvature for the corners. The rounded-corner
rectangle on the bitMap is filled with the pnPat, according to the
pattern transfer mode specified by pnMode. The pen location is not
changed by this procedure.
\ EraseRoundRect
2
PROCEDURE EraseRoundRect (r: Rect; ovalWidth,ovalHeight: INTEGER);

    EraseRoundRect paints the specified rounded-corner rectangle with
the current grafPort's background pattern bkPat (in patCopy mode).

    OvalWidth and ovalHeight specify the diameters of curvature for the
corners. The grafPort's pnPat and pnMode are ignored; the pen location 
is not changed.
\ InvertRoundRect
2
PROCEDURE InvertRoundRect (r: Rect; ovalWidth,ovalHeight: INTEGER);

    InvertRoundRect inverts the pixels enclosed by the specified
rounded-corner rectangle: every white pixel becomes black and every
black pixel becomes white. OvalWidth and ovalHeight specify the
diameters of curvature for the corners. The grafPort's pnPat, pnMode,
and bkPat are all ignored; the pen location is not changed.
\ FillRoundRect
2
PROCEDURE FillRoundRect (r: Rect; ovalWidth,ovalHeight: INTEGER; pat:
                            Pattern);

    FillRoundRect fills the specified rounded-corner rectangle with the
given pattern (in patCopy mode). OvalWidth and ovalHeight specify the
diameters of curvature for the corners. The grafPort's pnPat, pnMode, 
and bkPat are all ignored; the pen location is not changed.
\ FrameArc
2
PROCEDURE FrameArc (r: Rect; startAngle,arcAngle: INTEGER);

    FrameArc draws an arc of the oval that fits inside the specified
rectangle, using the current grafPort's pen pattern, mode, and size.
StartAngle indicates where the arc begins and is treated mod 36¯.
ArcAngle defines the extent of the arc. The angles are given in
positive or negative degrees; a positive angle goes clockwise, while a
negative angle goes counterclockwis. Zero degrees is at l2 o'clock,
high, 9¯ (or -27¯) is at 3 o'clock, 18¯ (or -18¯) is at 6 o'clock, and
27¯ (or -9¯) is at 9 o'clock. Other angles are measured relative to
the enclosing rectangle:  a line from the center of the rectangle
through its top right corner is at 45 degrees, even if the rectangle is
not square; a line through the bottom right corner is at 135 degrees,
and so on (see Figure 2¯).

    The arc is as wide as the pen width and as tall as the pen height.
It is drawn with the pnPat, according to the pattern transfer mode
specified by pnMode. The pen location is not changed by this
procedure.

(eye)
    FrameArc differs from other QuickDraw procedures that
    frame shapes in that the arc is not mathematically added
    to the boundary of a region that is open and being
    formed.


\ PaintArc
2
PROCEDURE PaintArc (r: Rec; startAngle,arcAngle: INTEGER);

    PaintArc paints a wedge of the oval just inside the specified
rectangle with the current grafPort's pen pattern and mode. StartAngle
and arcAngle define the arc of the wedge as in FrameArc. The wedge on
the bitMap is filled with the pnPat, according to the pattern transfer
mode specified by pnMode. The pen location is not changed by this
procedure.


\ EraseArc
2
PROCEDURE EraseArc (r: Rect; startAngle,arcAngle: INTEGER);

    EraseArc paints a wedge of the oval just inside the specified
rectangle with the current grafPort's background pattern bkPat (in
patCopy mode). StartAngle and arcAngle define the arc of the wedge as in
FrameArc. The grafPort's pnPat and pnMode are ignored; the pen location
is not changed.
\ InvertArc
2
PROCEDURE InvertArc (r: Rect; startAngle,arcAngle: INTEGER);

    InvertArc inverts the pixels enclosed by a wedge of the oval just
inside the specified rectangle:  every white pixel becomes black and
every black pixel becomes white. StartAngle and arcAngle define the
arc of the wedge as in FrameArc. The grafPort's pnPat, pnMode, and 
bkPat are all ignored; the pen location is not changed.
\ FillArc
2
PROCEDURE FillArc (r: Rect; startAngle,arcAngle: INTEGER; pat:
    Pattern);

    FillArc fills a wedge of the oval just inside the specified
rectangle with the given pattern (in patCopy mode). StartAngle and
arcAngle define the arc of the wedge as in FrameArc. The grafPort's
pnPat, pnMode, and bkPat are all ignored; the pen lcoation is not
changed.
\ NewRgn
2
FUNCTION NewRgn : RgnHandle;

    NewRgn allocates space for a new, dynamic, variable-size region,
initializes it to the empty region (¯,¯,¯,¯), and returns a handle to
the new region. Only this function creates new regions; all other
procedures just alter the size and shape of regions you create.
OpenPort calls NewRgn to allocate space for the port's visRgn and 
clipRgn.

(eye)
    Except when using visRgn or clipRgn, you MUST call NewRgn
    before specifying a region's handle in any drawing or 
    calculation procedure.

(eye)
    Never refer to a region without using its handle.
\ DisposeRgn
2
PROCEDURE DisposeRgn (rgn: RgnHandle);

    DisposeRgn deallocates space for the region whose handle is supplied
and returns the memory used by the region to the free memory pool. Use
this only after you are completely through with a temporary region.

(eye)
    Never use a region once you have deallocated it, or you
    will risk being hung by dangling pointers!
\ CopyRgn
2
PROCEDURE CopyRgn (srcRgn,dstRgn: RgnHandle);

    CopyRgn copies the mathematical structure of arcRgn into dstRgn;
that is, it makes a duplicate copy of srcRgn. Once this is done, srcRgn
may be altered (or even disposd of) without affecting dstRgn. COPYRGN
DOES NOT CREATE THE DESTINATION REGION:  you must use NewRgn to create
the dstRgn before you call CopyRgn.
\ SetEmptyRgn
2
PROCEDURE SetEmptyRgn (rgn: RgnHandle);

    Set EmptyRgn destroys the previous structure of the given region,
then sets the new structure to the empty region (¯,¯,¯,¯).
\ SetRectRgn
2
PROCEDURE SetRectRgn (rgn: RgnHandle; left,top,right,bottom: INTEGER);

    SetRectRgn destroys the previous structure of the given region, then
sets the new structure to the rectangle specified by left, top, right,
and bottom.

    If the specified rectangle is empty (i.e., left>=right or
top>=Bottom), the region is set to the empty region (¯,¯,¯,¯).
\ RectRgn
2
PROCEDURE RectRgn (rgn: RgnHandle; r: Rect);

    RectRgn destroys the previous structure of the given region, then
sets the new structure to the rectangle specified by r. This is
operationally synonymous with SetRectRgn, except the input rectangle is
defined by a rectangle rather than by four boundary coordinates.
\ OpenRgn
2
PROCEDURE OpenRgn;

    OpenRgn tells QuickDraw to allocate temporary space and start saving
lines and framed shapes for later processing as a region definition.
While a region is open, all calls to Line, LineTo, and the procedures
that draw framed shapes (except arcs) affect the outline of the region.
Only the line endpoints and shape boundaries affect the region
definition; the pen mode, pattern, and size do not affect it. In fact,
OpenRgn calls HidePen, so no drawing occurs on the screen while the
region is open (unless you called ShowPen just after Open Rgn, or you
called ShowPen previously without balancing it by a call to HidePen).
Since the pen hangs below and to the right of the pen location, drawing
lines with even the smallest pen will change bits that lie outside the
region you define.

    The outline of a region is mathematically defined and infinitely
thin, and separates the bitMap into two groups of bits:  those within
the region and those outside it. A region should consist of one or more
closed loops. Each framed shape itself constitutes a loop. Any lines
drawn with Line or LineTo should connect with each other or with a
framed shape. Even though  the on-screen presentation of a region is
clipped, the definition of a region is not; you can define a region
anywhere on the coordinate plane with complete disregard for the
location of various grafPort entities on that plane.

    When a region is open, the current grafPort's rgnSave field contains
a handle to information related to the region definition. If you want
to temporarily disable the collection of lines and shapes, you can save
the current value of this field, set the field to NIL, and later
restore the saved value to resume the region definition.

(eye)
    Do not call OpenRgn while another region is already open.
    All open regions but the most recent will behave
    strangely.
\ CloseRgn
2
PROCEDURE CloseRgn (dstRgn: RgnHandle);

    CloseRgn stops the collection of lines and framed shapes, organizes
them into a region definition, and saves the resulting region into the
region indicated by dstRgn. You should perform one and only one
CloseRgn for every OpnRgn. CloseRgn calls ShowPen, balancing the
HidePen call made by OpenRgn.

    Here's an example of how to create and open a region, define a
barbell shape, close the region, and draw it:

    barbell := NewRgn;                  {make a new region}
    OpenRgn;                            {begin collecting stuff}
       SetRect(tempRect,2¯,2¯,3¯,5¯);   {form the left weight}
       FrameOval(tempRect);
       SetRect(tempRect,3¯,3¯,8¯,4¯);   {form the bar}
       FrameRect(tempRect);
       SetRect(tempRect(8¯,2¯,9¯,5¯);   {form the right weight}
       FrameOval(tempRect);
    CloseRgn(barbell);                  {we're done; save in barbell}
    FillRgn(barbell,black);             {draw it on the screen}
    DisposeRgn(barbell);                {we don't need you anymore...}
\ OffsetRgn
2
PROCEDURE OffsetRgn (rgn: RgnHandle; dh,dv: INTEGER);

    OffsetRgn moves the region on the coordinate plane, a distance of dh
horizontally and dv vertically. This does not affect the screen unless
you subsequently call a routine to draw the region. If dh and dv are
positive, the movement is to the right and down; if either is negative,
the corresponding movement is in the opposite direction. The region
retains its size and shape.

(hand)
    OffsetRgn is an especially efficient operation, because
    most of the data defining a region is stored relative to
    rgnBBox and so isn't actually changed by OffsetRgn.
\ InsetRgn
2
PROCEDURE InsetRgn (rgn: RgnHandle; dh,dv: INTEGER);

    InsetRgn shrinks or expands the region. All points on the region
boundary are moved inwards a distance of dv vertically and dh
horizontally; if dh or dv is negative, the points are moved outwards in
that direction. InsetRgn leaves the region "centered" at the same
position, but moves the outline in (for positive values of dh and dv)
or out (for negative values of dh and dv). InsetRgn of a rectangular
region works just like InsetRect.
\ SectRgn
2
PROCEDURE SectRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);

    SectRgn calculates the intersection of two regions and places the
intersection in a third region. THIS DOES NOT CREATE THE DESTINATION
REGION:  you must use NewRgn to create the dstRgn before you call
SectRgn. The dstRgn can be one of the source regions, if desired.

    If the regions do not intersect, or one of the regions is empty, the
destination is set to the empty region (¯,¯,¯,¯).
\ UnionRgn
2
PROCEDURE UnionRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);

    UnionRgn calculates the union of two regions and places the union in
a third region. THIS DOES NOT CREATE THE DESTINATION REGION:  you must
use NewRgn to create the dstRgn before you call UnionRgn. The dstRgn
can be one of the source regions, if desired.

    If both regions are empty, the destination is set to the empty
region (¯,¯,¯,¯).
\ DiffRgn
2
PROCEDURE DiffRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);

    DiffRgn subtracts  srcRgnB from srcRgnA and places the difference in
a third region. THIS DOES NOT CREATE THE DESTINATION REGION:  You must
use NewRgn to create the dstRgn before you call DiffRgn. The dstRgn
can be one of the source regions, if desired.

    If the first source region is empty, the destination is set to the
empty region (¯,¯,¯,¯).
\ XorRgn
2
PROCEDURE XorRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle);

    XorRgn calculates the difference between the union and the
intersection of two regions and places the result in a third region.
THIS DOES NOT CREATE THE DESTINATION REGION:  you must use NewRgn to
create the dstRgn before you call XorRgn. The dstRgn can be one of the
source regions, if desired.

    If the regions are coincident, the destination is set to the empty
region (¯,¯,¯,¯).
\ PtInRgn
2
FUNCTION PtInRgn (pt: Point; rgn: RgnHandle) : BOOLEAN;

    PtInRgn checks whether the pixel below and to the right of the given
coordinate point is within the specified region, and returns TRUE if so
or FALSE if not.
\ RectInRgn
2
FUNCTION RectInRgn (r: Rect; rgn: RgnHandle) : BOOLEAN;

    RectInRgn checks whether the given rectangle intersects the
specified region, and returns TRUE if the intersection encloses at least one bit
or FALSE if not.
\ EqualRgn
2
FUNCTION EqualRgn (rgnA,rgnB: RgnHandle) : BOOLEAN;

EqualRgn compares the two regions and returns TRUE if they are equal
or FALSE if not. The two regions must have identical sizes, shapes, and
locations to be considered equal. Any two empty regions are always
equal.
\ EmptyRgn
2
FUNCTION EmptyRgn (rgn: RgnHandle) : BOOLEAN;

    EmptyRgn returns TRUE if the region is an empty region or FALSE if
not. Some of the circumstances in which an empty region can be created
are: a NewRgn call; a CopyRgn of an empty region; a SetRectRgn or
RectRegn with an empty rectangle as an argument; CloseRgn without a
previous OpenRgn or with no drawing after an OpenRgn; OffsetRgn of an
empty region; InsetRgn with an empty region or too large an inset;
SectRgn of nonintersecting regions; UnionRgn of two empty regions; and
DiffRgn or XorRgn of two identical or nonintersecting regions.
\ FrameRgn
2
PROCEDURE FrameRgn (rgn: RgnHandle);

    FrameRgn draws a hollow outline just inside the specified region,
using the current grafPort's pen pattern, mode, and size. The outline
is as wide as the pen width and as tall as the pen height; under no
circumstances will the frame go outside the region boundary. The pen
location is not changed by this procedure.

    If a region is open and being formed, the outside outline of the
region being framed is mathematically added to that region's boundary.
\ PaintRgn
2
PROCEDURE PaintRgn (rgn: RgnHandle);

    PaintRgn paints the specified region with the current grafPort's pen 
pattern and pen mode. The region on the bitMap is filled with the
pnPat, according to the pattern transfer mode specified by pnMode. The
pen location is not changed by this procedure.
\ EraseRgn
2
PROCEDURE EraseRgn (rgn: RgnHandle);

    EraseRgn paints the specified region with the current grafPort's
background pattern bkPat (in patCopy mode). The grafPort's pnPat and 
pnMode are ignored; the pen location is not changed.
\ InvertRgn
2
PROCEDURE InvertRgn (rgn: RgnHandle);

    InvertRgn inverts the pixels enclosed by the specified region: every
white pixel becomes black and every black pixel becomes white. The
grafPort's pnPat, pnMode, and bkPat are all ignored; the pen lcoation 
is not changed.
\ FillRgn
2
PROCEDURE FillRgn (rgn: RgnHandle; pat: Pattern);

    FillRgn fills the specified region with the given pattern (in
patCopy mode). The grafPort's pnPat, pnMode, and bkPat are all ignored;
the pen location is not changed.
\ ScrollRect
2
PROCEDURE ScrollRect (r: Rect; dh,dv: INTEGER; updateRgn: RgnHandle);

    ScrollRect shifts ("scrolls") those bits inside the intersection of
the specified rectangle, visRgn, clipRgn, portRect, and portBits.bounds.
The bits are shifted a distance of dh horizontally and dv vertically.
The positive directions are to the right and down. No other bits are
affected. Bits that are shifted out of the scroll area are lost; they
are neither placed outside the area nor saved. The grafPort's
background pattern bkPat fills the space created by the scroll. In
addition, updateRgn is changed to the area filled with bkPat (see
Figure 21).

    Figure 21 shows that the pen location after a ScrollRect is in a
different position relative to what was scrolled in the rectangle. The
entire scrolled item has been moved to different coordinates. To
restore it to its coordinates before the ScrollRect, you can use the
SetOrigin procedure. For example, suppose the dstRect here is the
portRect of the grafPort and its top left corner is at (95,12¯).
SetOrigin(1¯5,115) will offset the coordinate system to compensate for
the scroll. Since the clipRgn and pen lcoation are not offset, they
move down and to the left.
\ CopyBits
2
PROCEDURE CopyBits (srcBits,dstBits: BitMap; srcRect,dstRect: Rect;
        mode: INTEGER; maskRgn: RgnHandle);

    CopyBits transfers a bit image between any two bitMaps and clips the
result to the area specified by the maskRgn parameter. The transfer
may be performed in any of the eight source transfer modes. The result
is always clipped to the maskRgn and the boundary rectangle of the
destination bitMap; if the destination bitMap is the current grafPort's 
portBits, it is also clipped to the intersection of the grafPort's 
clipRgn and visRgn. If you do not want to clip to a maskRgn, just pass
NIL for the maskRgn parameter.

    The dstRect and maskRgn coordinates are in terms of the
dstBits.bounds coordinate system, and the src Rect coordinates are in
terms of the srcBits.bounds coordinates.

    The bits enclosed by the source rectangle are transferred into the
destination rectangle according to the rules of the chosen mode. The
source transfer modes are as follows:

    srcCopy     srcXor      notSrcCopy  notSrcXor
    srcOr       srcBic      notSrcOr    notSrcBic

    The source rectangle is completely aligned with the destination
rectangles; if the rectangles are of different sizes, the bit image is
expanded or shrunk as necessary to fit the destination rectangle. For
example, if the bit image is a circle in a square source rectangle, and
the destination rectangle is not square, the bit image appears as an
oval in the destination (see Figure 22).
\ OpenPicture
2
FUNCTION  OpenPicture (picFrame: Rect) : PicHandle;

    OpenPicture returns a hendle to a new picture  which has the given
rectangle as its picture frame, and tells QuickDraw to start saving as
the picture definition all calls to drawing routines and all picture
comments (if any).

    OpenPicture calls HidePen, so no drawing occurs on the screen while
the picture is open (unless you call ShowPen just after OpenPicture, or
you called ShowPen previously without balancing it by a call to HidePen)

    When a picture is open, the current grafPort's picSave field
contains a handle to information related to the picture definition. If
you want to temporarily disable the collection of routine calls and
picture comments, you can save the current value of this field, set the
field to NIL, and later restore the saved value to resume the picture
definition.

(eye)
    Do not call OpenPicture while another picture is already
    open.
\ ClosePicture
2
PROCEDURE ClosePicture;

    ClosePicture tells QuickDraw to stop saving routine calls and
picture comments as the definition of the currently open picture. You
should perform one and only one ClosePicture for every OpenPicture.
ClosePicture calls ShowPen, balancing the HidePen call made by
OpenPicture.
\ PicComment
2
PROCEDURE PicComment (kind,dataSize: INTEGER; dataHandle: QDHandle);

    PicComment inserts the specified comment into the definition of the
currently open picture.  Kind identifies the type of comment.
DataHandle is a handle to additional data if desired, and dataSize is
the size of that data in bytes. If there is no additional data for the
comment, dataHandle should be NIL and dataSize should be ¯. The
application that processes the comment must include a procedure to do
the processing and store a pointer to the procedure in the data
structure pointed to by the grafProcs field of the grafPort (see
"Customizing QuickDraw Operations").
\ DrawPicture
2
PROCEDURE DrawPicture (myPicture: PicHandle; dstRect: Rect);

    DrawPicture draws the given picture to scale in dstRect, expanding
or shrinking it as necessary to align the borders of the picture frame
with dstRect. DrawPicture passes any picture comments to the procedure
accessed indirectly through the grafProcs field of the grafPort (see
PicComment above).
\ KillPicture
2
PROCEDURE KillPicture (myPicture: PicHandle);

    KillPicture deallocates space for the picture whose handle is
supplied, and returns the memory used by the picture to the free memory
pool. Use this only when you are completely through with a picture.
\ OpenPoly
2
FUNCTION OpenPoly : PlyHandle;

    OpenPoly returns a handle to a new polygon and tells QuickDraw to
start saving the polygon definition as specified by calls to
line-drawing routines. While a polygon is open, all calls to Line and
LineTo affect the outline of the polygon. Only the line endpoints
affect the polygon definition; the pen mode, pattern, and size do not
affect it. In fact OpenPoly calls HidePen, so no drawing occurs on the
screen while the polygon is open (unless you call ShowPen just after
OpenPoly, or you called ShowPen previously without balancing it by a
call to HidePen).

    A polygon should consist of a sequence of connected lines. Even
though the on-screen presentation of a polygon is clipped, the
definition of a polygon is not; you can define a polygon anywhere on the
coordinate plane with complete disregard for the location of various
grafPort entities on that plane.

    When a polygon is open, the current grafPort's polySave field
contains a handle to information related to the polygon definition. If
you want to temprarily disable the polygon definition, you can save the
current value of this field, set the field to NIL, and later restore the
saved value to resume the polygon definition.

(eye)
    Do not call OpenPoly while another polygon is already
    open.
\ ClosePoly
2
PROCEDURE ClosePoly;

    ClosePoly tells QuickDraw to stop saving the definition of the
currently open polygon and computes the polyBBox rectangle. You should
perform one and only one ClosePoly for every OpenPoly. ClosePoly calls
ShowPen, balancing the HidePen call made by OpenPoly.

    Here's an example of how to open a polygon, define it as a triangle, 
close it, and draw it:

    triPoly := OpenPoly;    {save handle and begin collecting stuff}
      MoveTo (3¯¯,1¯¯);     { move to first point and }
      LineTo(4¯¯,2¯¯);      {      form       }
      LineTo(2¯¯,2¯¯);      {       the           }
      LineTo(3¯¯,1¯¯);      {     triangle    }
    ClosePoly;              {stop collecting stuff}
    FillPoly(triPoly,gray); {draw it on the screen}
    KillPoly(triPoly);      {we're all done}
\ KillPoly
2
PROCEDURE KillPoly (poly: PolyHandle);

    KillPoly deallocates space for the polygon whose handle is supplied,
and returns the memory used by the polygon to the free memory pool.
Use this only after you are completely through with a polygon.
\ OffsetPoly
2
PROCEDURE OffsetPoly (poly: PolyHandle; dh,dv: INTEGER);

    OffsetPoly moves the polygon on the coordinate plane, a distance of
dh horizontally and dv vertically. This does not affect the screen
unless your subsequently call a routine to draw the polygon. If dh and
dv are positive, the movement is to the right and down; if either is
negative, the corresponding movement is in the opposite direction. The
polygon retains its shape and size.

(hand)
    OffsetPoly is an especially efficient operation, because
    the data defining a polygon is stored relative to
    polyStart and so isn't actually changed by OffsetPoly.
\ FramePoly
2
PROCEDURE FramePoly (poly: PolyHandle);

    FramePoly plays back the line-drawing routine calls that define the
given polygon, using the current grafPort's pen pattern, mode, and 
size. The pen will hang below and to the right of each point on the
boundary of the polygon; thus, the polygon drawn will extend beyond the
right and bottom edges of poly^^.polyBBox by the pen width and pen
height, respectively. All other graphic operations occur strictly
within the boundary of the polygon, as for other shapes. You can see
this difference in Figure 23, where each of the polygons is shown with
its polyBBox.

    If a polygon is open and being formed, FramePoly affects the outline
of the polygon just as if the line-drawing routines themselves had been
called. If a region is open and being formed, the outside outline of
the polygon being framed is mathematically added to the region's
boundary.
\ PaintPoly
2
PROCEDURE PaintPoly (poly: PolyHandle);

    PaintPoly paints the specified polygon with the current grafPort's
pen pattern and pen mode. The polygon on the bitMap is filled with the
pnPat, according to the pattern transfer mode specified by pnMode. The
pen location is not changed by this procedure.
\ ErasePoly
2
PROCEDURE ErasePoly (poly: PolyHandle);

    ErasePoly paints the specified polygon with the current grafPort's 
background pattern bkPat (in patCopy mode). The pnPat and pnMode are
ignored; the pen location is not changed.
\ InvertPoly
2
PROCEDURE InvertPoly (poly: PolyHandle);

    InvertPoly inverts the pixels enclosed by the specified polygon:
every white pixel becomes black and every black pixel becomes white. The
grafPort's pnPat, pnMode, and bkPat are all ignored; the pen location
is not changed.
\ FillPoly
2
PROCEDURE FillPoly (poly: PolyHandle; pat: Pattern);

    FillPoly fills the specified polygon with the given pattern (in
patCopy mode.)  The grafPort's pnPat, pnMode, and bkPat are all ignored;
the pen location is not changed.
\ AddPt
2
PROCEDURE AddPt (srcPt: Point; VAR dstPt: Point);

    AddPt adds the coordinates of srcPt to the coordinates of dstPt, and
returns the result in dstPt.
\ SubPt
2
PROCEDURE SubPt (srcPt: Point; VAR dstPt: Point);

    SubPt subtracts the coordinates of srcPt from the coordinates of
dstPt, and returns the result in dstPt.
\ SetPt
2
PROCEDURE SetPt (VAR pt: Point; h,v: INTEGER);

    SetPt assigns two integer coordinates to a variable of type Point.
\ EqualPt
2
FUNCTION EqualPt (ptA,ptB: Point) : BOOLEAN;

    EqualPt compares the two points and returns true if they are equal
or FALSE if not.
\ LocalToGlobal
2
PROCEDURE LocalToGlobal (VAR pt: Point);

    LocalToGlobal converts the given point from the current grafPort's
local coordinate system into a global coordinate system with the origin
(¯,¯) at the top left corner of the port's bit image (such as the 
screen). This global point can then be compared to other global
points, or be changed into the local coordinates of another grafPort.

    Since a rectangle is defined by two points, you can convert a
rectangle into global coordinates by performing two LocalToGlobal calls,
You can also convert a rectangle, region, or polygon into global
coordinates by calling OffsetRect, OffsetRgn, or OffsetPoly. For
examples, see GlobalToLocal below.
\ GlobalToLocal
2
PROCEDURE GlobalToLocal (VAR pt: Point);

    GlobalToLocal takes a point expressed in global coordinates (with
the top left corner of the bitMap as coordinate (¯,¯)) and converts it
into the local coordinates of the current grafPort. The global point
can be obtained with the LocalToGlobal call (see above). For example,
suppose a game draws a "ball" within a rectangle named ballRect, defined
in the grafPort named gamePort (as illustrated below in Figure 24). If
you want to draw that ball in the grafPort named selectPort, you can
calculate the ball's selectPort coordinates like this:

    SetPort(gamePort);                  {start in origin port}
    selectBall:= ballRect;              {make a copy to be moved}
    LocalToGlobal(selectBall.topLeft);  {put both corners into }
    LocalToGlobal(selectBall.botRight); {  global coordinates  }

    SetPort(selectPort);                {switch to destination port}
    GlobalToLocal(selectBall.topLeft);  {put both corners into     }
    GlobalToLocal(selectBall.botRight); {  these local coordinates }
    FillOval(selectBall,ballColor);     {now you have the ball!}

    You can see from Figure 24 that LocalToGlobal and GlobalToLocal
simply offset the coordinates of the rectangle by the coordinates of the
top left corner of the local grafPort's boundary rectangle. You could
also do this with OffsetRect. In fact the way to convert regions and
polygons from one coordinate system to another is with OffsetRgn or
OffsetPoly rather than LocalToGlobal and GlobalToLocal. For example,
if myRgn were a region enclosed by a rectangle having the same
coordinates as ballRect in gamePort, you could convert the region to
global coordinates with

    OffsetRgn(myRgn, -2¯, -4¯);

and then convert it to the coordinates of the selectPort grafPort with

    OffsetRgn(myRgn, l5, -3¯);
\ Random
2
FUNCTION Random : INTEGR;

    This function returns an integer, uniformly distributedpseudo-
random, in the range from -32768 through 32767. The value returned
depends on the global variable randSeed, which InitGraf initializes to
1; you can start the sequence over again from where it began by
resetting randSeed to 1.
\ GetPixel
2
FUNCTION GetPixel (h,v: INTEGER) : BOOLEAN;

    GetPixel looks at the pixel associated with the given coordinate
point and returns TRUE if it is black or FALSE if it is white. The
selected pixel is immediately below and to the right of the point whose
coordinates are given in h and v, in the local coordinates of the
current grafPort. There is no guarantee that the specified pixel
actually belongs to the port, however; it may have been drawn by a port
overlapping the current one. To see if the point indeed belongs to the
current port, perform a PtInRgn(pt,thePort^.visRgn).
\ StuffHex
2
PROCEDURE StuffHex (thingPtr: QDPtr; s: Str255);

    StuffHex pokes bits (expressed as a string of hexadecimal digits)
into any data structure. This is a good way to create cursors, patterns,
or bit images to be "stamped" onto the screen with CopyBits. For
example,

    StuffHex(@stripes,'¯1¯2¯4¯81¯2¯4¯8¯')

places a striped pattern into the pattern variable stripes.

(eye)
    There is no range checking on the size of the destination
    variable. It's easy to overrun the variable and destroy 
    something if you don't know what you're doing.
\ ScalePt
2
PROCEDURE ScalePt (VAR pt: Point; srcRect,dstRect: Rect);

    A width and height are passed in pt; the horizontal component of pt
is the width, and the vertical component of pt is the height. ScalePt
scales these measurements as follows and returns the result in pt: it
multiplies the given width by the ratio of dstRect's width to srcRect's
width, and multiplies the given height by the ratio of dstRec's height 
to srcRect's height. In Figure 25, where dstRect's width is twice
srcRect's width and its height is three times srcRect's height, the pen
width is scaled from 3 to 6 and the pen height is scaled from 2 to 6.
\ MapPt
2
PROCEDURE MapPt (VAR pt: Point; srcRect,dstRect: Rect);

    Given a point within srcRect, MapPt maps it to a similarly located
point within dstRect (that is, to where it would fall if it were part
of a drawing being expanded or shrunk to fit dstRect). The result is
returned in pt. A corner point of srcRect would be mapped to the
corresponding corner point of dstRect, and the center of srcRect to the
center of dstRect. In Figure 25 above, the point (3.2) in srcRect is
mapped to (l8,7) in dstRect. FromRect and dstRect may overlap, and pt
need not actually be within srcRect.

(eye)
    Remember, if you are going to draw inside the rectangle
    in dstRect, you will probably also want to scale the pen
    size accordingly with ScalePt.
\ MapRect
2
PROCEDURE MapRect (VAR r: Rect; srcRect,dstRect: Rect);

    Given a rectangle within srcRect, MapRect maps it to a similarly
located rectangle within dstRect by calling MapPt to map the top left
and bottom right corners of the rectangle. The result is returned in
r.
\ MapRgn
2
PROCEDURE MapRgn (rgn: RgnHandle; srcRect: Rect);

    Given a region within srcRec, MapRgn maps it to a similarly located
region within dstRect by calling MapPt to map all the points in the
region.
\ MapPoly
2
PROCEDURE MapPoly (poly: PolyHandle; srcRect,dstRect: Rect);

    Given a polygon within srcRect, MapPoly maps it to a similarly
located polygon within dstRect by calling MapPt to map all the pointsthat
define the polygon.
\ SetStdProcs
2
PROCEDURE SetStdProcs (VAR procs: QDProcs);

    This procedure sets all the fields of the given QDProcs record to
point to the standard low-level routines. You can then change the ones
you wish to point to your own routines. For example, if your procedure
that processes picture comments is named MyComments, you will store
@MyComments in the commentProc field of the QD Procs record.

    The routines you install must of course have the same calling
sequences as the standard routines, which are described below. The
standard drawing routines tell which graphic operation to perform from a
parameter of type GrafVerb.

    TYPE GrafVerb = (frame, paint, erase, invert, fill);

    When the grafVerb is fill, the pattern to use when filling is passed
in the fillPat field of the grafPort.
\ StdText
2
PROCEDURE StdText (byteCount: INTEGER; textBuf: QDPtr; numer,denom:
        INTEGER);

    StdText is the standard low-level routine for drawing text. It draws
text from the arbitrary structure in memory specified by textBuf,
starting from the first byte and continuing for byteCount bytes. Numer
and denom specify the scaling, if any:  numer.v over denom.v gives the
vertical scaling, and numer.h over denom.h gives the horizontal
scaling.
\ StdLine
2
PROCEDURE StdLine (newPt: Point);

    StdLine is the standard low-level routine for drawing a line. It
draws a line from the current pen location to the location specified (in
local coordinates) by newPt.
\ StdRect
2
PROCEDURE StdRect (verb; r: Rect);

    StdRect is the standard low-level routine for drawing a rectangle.
It draws the given rectangle according to the specified grafVerb.
\ StdRRect
2
PROCEDURE StdRRect (verb: GrafVerb; r: Rect; ovalwidth,ovalHeight:
                    INTEGER);

    StdRrect is the standard low-level routine for drawing a rounded-
corner rectangle. It draws the given rounded-corner rectangle according
to the specified grafVerb. OvalWidth and ovalHeight specify the
diameters of curvature for the corners.
\ StdOval
2
PROCEDURE StdOval (verb: GrafVerb; r: Rect);

    StdOval is the standard low-level routine for drawing an oval. It
draws an oval inside the given rectangle according to the specified
grafVerb.
\ StdArc
2
PROCEDURE StdArc (verb: GrafVerb; r: Rect; startAngle,arcAngle:
                    INTEGER);

    StdArc is the standard low-level routine for drawing an arc or a
wedge. It draws an arc or wedge of the oval that fits inside the given
rectangle. The grafVerb specifies the graphic operation; it it's the 
frame operation, an arc is drawn; otherwise, a wedge is drawn.
\ StdPoly
2
PROCEDURE StdPoly (verb: GrafVerb; poly: PolyHandle);

    StdPoly is the standard low-level routine for drawing a polygon. It
draws the given polygon according to the specified grafVerb.
\ StdRgn
2
PROCEDURE StdRgn (verb: GrafVerb; rgn: RgnHandle);

    StdRgn is the standard low-level routine for drawing a region. It
draws the given region according to the specified grafVerb.
\ StdBits
2
PROCEDURE StdBits (VAR srcBits: BitMap; VAR srcRect,dstRect: Rect;
                    mode: INTEGER; maskRgn: RgnHandle);

    StdBits is the standard low-level routine for doing bit transfer.It
transfers a bit image between the given bitMap and thePort^.portBits,
just as if CopyBits were called with the same parameters and with a
destination bitMap equal to thePort^.portBits.
\ StdComment
2
PROCEDURE StdComment (kind,dataSize: INTEGER; dataHandle: QDHandle);

    StdComment is the standard low-level routine for processing a
picture comment. Kind identifies the type of comment. DataHandle is a
handle to additional data, and dataSize is the size of that data in
bytes. If there is no additional data for the command, dataHandle will
be NIL and dataSize will be ¯. StdComment simply ignores the comment.
\ StdTxMeas
2
FUNCTION StdTxMeas (byteCount: INTEGER; textBuf: QDPtr; VAR
                    numer,denom: Point; VAR info: FontInfo) : INTEGER;

    StdTxMeas is the standard low-level routine for measung text width.
It returns the width of the text stored in the arbitrary structure in
memory specified by textBuf, starting with the first byte and
continuing for byteCount bytes. Numer and denom specify the scaling as
in the StdText procedure; note that StdTxMeas may change them.
\ StdGetPic
2
PROCEDURE StdGetPic (dataPtr: QDPtr; byteCount: INTEGER);

    StdGetPic is the standard low-level routine for retrieving
information from the definition of a picture. It retrieves the next
byteCount bytes from the definition of the currently open picture and
stores them in the data structure pointed to by dataPtr.
\ StdPutPic
2
PROCEDURE StdPutPic (dataPtr: QdPtr; byteCount: INTEGER);

    StdPutPic is the standard low-level routine for saving information
as the definition of a picture. It saves as the definition of the
currently open picture the drawing commands stored in the data
structure pointed to by dataPtr, starting with the first byte and
continuing for the next byteCount bytes.
\ SeedFill
2
PROCEDURE SeedFill (srcPtr,dstPtr: Ptr; srcRow, dstRow, height,
                    words,seedH,seedV: INTEGER);

    Given a source bit image, SeedFill computes a destination bit image
with 1Õs only in the pixels where paint can leak from the starting
seed point, like the MacPaint paint-bucket tool. SeedH and seedV
specify horizontal and vertical offsets, in pixels, from the beginning
of the data pointed to by dstPtr, determining how far into the
destination bit image filling should begin. Calls to SeedFill are not
clipped to the current port and are not stored into QuickDraw pictures.
\ CalcMask
2
PROCEDURE CalcMask (srcPtr,dstPtr: Ptr; srcRow, dstRow, height,
                    words: INTEGER);

    Given a source bit image, CalcMask computes a destination bit image
with 1Õs only in the pixels where paint could not leak from any of
the outer edges, like the MacPaint lasso tool. Calls to CalcMask are
not clipped to the current port and are not stored into QuickDraw
pictures.
\ CopyMask
2
PROCEDURE CopyMask (srcBits,maskBits,dstBits: BitMap; srcRect,
                    maskRect,dstRect: Rect);

    CopyMask is a new version of the CopyBits procedure; it transfers a
bit image from the source bitmap to the destination bitmap only where
the corresponding bit of the mask rectangle is a 1. (Note that
the mask is specified as a rectangle instead of as a handle to a region.)  It can be used along with CalcMask to implement the lasso copy as in MacPaint; itÕs also useful for drawing icons. CopyMask doesnÕt check for overlap between the source and destina
\ MeasureText
2
PROCEDURE MeasureText (count: INTEGER; textAddr,charLocs: Ptr);

    This procedure is designed to improve performance in specialized
applications such as word processors by providing an array version of
the TextWidth function; itÕs like calling TextWidth repeatedly for a
given set of characters. TextAddr points to an arbitrary piece of text
in memory, and count specifies how many characters are to be measured.

    MeasureText moves along the string and, for each character, computes
the distance from TextAddr to the right edge of the character.
CharLocs should point to an array of count + 1 integers. Upon return,
the first element in the array will always contain 0; the other elements
will contain pixel positions on the screen for all of the specified
characters.

Note:   MeasureText only works with text displayed on the screen;
        since it doesnÕt go through the QuickDraw procedure StdText, it
        canÕt be used to measure text to be printed.

\ GetMaskTable
2
    The function GetMaskTable, accessible only from assembly language,
returns in register A0 a pointer to a ROM table containing the following
useful masks:

.WORD $0000,$8000,$C000,$E000   ;Table of 16 right masks
.WORD $F000,$F800,$FC00,$FE00
.WORD $FF00,$FF80,$FFC0,$FFE0
.WORD $FFF0,$FFF8,$FFFC,$FFFE

.WORD $FFFF,$7FFF,$3FFF,$1FFF   ;Table of 16 left masks
.WORD $0FFF,$07FF,$03FF,$01FF
.WORD $00FF,$007F,$003F,$001F
.WORD $000F,$0007,$0003,$0001

.WORD $8000,$4000,$2000,$1000   ;Table of 16 bit masks
.WORD $0800,$0400,$0200,$0100
.WORD $0080,$0040,$0020,$0010
.WORD $0008,$0004,$0002,$0001

_GetMaskTable : Macro Name.
\ InitFonts
3
PROCEDURE InitFonts;

    InitFonts initializes the Font Manager. If the system font isn't
already in memory, InitFonts reads it into memory. Call this procedure
once before all other Font Manager routines or any Toolbox routine that
will call the Font Manager.
\ GetFontName
3
PROCEDURE GetFontName (fontNum: INTEGER; VAR theName: Str255);

    GetFontName returns in theName the name of the font having the font
number fontNum. If there's no such font, GetFontName returns the empty
string.
\ GetFNum
3
PROCEDURE GetFNum (fontName: Str255; VAR theNum: INTEGER);

    GetFNum returns in theNum the font number for the font having the
given fontName. If there's no such fone getFNum returns ¯.
\ RealFont
3
FUNCTION RealFont (fontNum: INTEGER; size: INTEGER) : BOOLEAN;

    RealFont returns TRUE if the font having the font number fontNum is
available in the given size in a resource file, or FALSE if the font
has to be scaled to that size.
\ SetFontLock
3
PROCEDURE SetFontLock (lockFlag: BOOLEAN);

    SetFontLock applies to the font in which text was most recently
drawn; it makes the font unpurgeable if lockFlag is TRUE or purgeable if
lockFlag is FALSE. Since fonts are normally purgeable, this procedure
is useful for making a font temporarily unpurgeable.
\ SwapFont
3
FUNCTION SwapFont (inRec: FMInput) : FMOutPtr;

    SwapFont returns a pointer to an FMOutput record containing the
size, style, and other information about an adapted version of the font
requested in the given FMInput record. (FMInput and FMOutput records
are explained in the following section.)  SwapFont is called by
QuickDraw every time a QuickDraw routine that does anything with text
is used. If you want to call SwapFont yourself, you must build an
FMInput record and then use the returned pointer to access the
resulting FMOutput record.
\ FontMetrics
3
PROCEDURE FontMetrics (VAR theMetrics: FMetricRec);

    FontMetrics is similar to the QuickDraw procedure GetFontInfo except
that it returns fixed-point values for greater accuracy in
high-resolution printing.

The FMetricRec data structure is defined as follows:

TYPE FMetricRec = RECORD
         ascent:    Fixed;  {ascent}
         descent:   Fixed;  {descent}
         leading:   Fixed;  {leading}
         widMax:    Fixed;  {maximum character width}
         wTabHandle:    Handle; {handle to global width table}
       END;

    Ascent, descent, leading, and widMax are identical in function to
their counterparts in GetFontInfo. WTabHandle is a handle to the
global width table (described below).

\ SetFractEnable
3
PROCEDURE SetFractEnable (fractEnable: BOOLEAN)   [Not in ROM]

    SetFractEnable lets you enable or disable fractional character
widths. If fractEnable is TRUE, fractional character widths are enabled;
if itÕs FALSE, the Font Manager uses integer widths. To ensure
compatibility with existing applications, fractional character widths
are disabled by default.
___________________________________________________________________

Assembly-language note:  From assembly language, you can change the
value of the global variable FractEnable.
___________________________________________________________________
\ SetFScaleDisable
3
PROCEDURE SetFScaleDisable (fontScaleDisable: BOOLEAN);

    SetFScaleDisable lets you disable or enable font scaling.
If fontScaleDisable is TRUE, font scaling is disabled and
the Font Manager returns an unscaled font with more space around
the characters; if itÕs FALSE, the Font Manager scales fonts.
To ensure compatibility with existing applications, the Font Manager
defaults to scaling fonts.

    ______________________________________________________________
    Assembly-language note:  All programmers should use the
    SetFScaleDisable procedure to disable and enable font scaling.
    In particular, setting the global variable FScaleDisable is
    insufficient.
    ______________________________________________________________
\ GetNextEvent
4
FUNCTION GetNextEvent (eventMask: INTEGER; VAR theEvent: EventRecord)
                        : BOOLEAN;

    GetNextEvent returns the next available event of a specified type or
types and, if the event is in the event queue, removes it from the
queue. The event is returned as the value of the parameter theEvent.
The eventMask parameter specifies which event types are of interest.
GetNextEvent returns the next available event of any type designated by
the mask, subject to the priority rules discussed above under "Priority
of Events". If no event of any of the designated types is available,
GetNextEvent returns a null event.

(note)
    Events in the queue that aren't designated in the mask 
    are kept in the queue; if you want to remove them, you
    can do so by calling the Operating System Event Manager
    procedure FlushEvents.

    Before reporting an event to your application, GetNextEvent first
calls the Desk Manager function System Event to see whether the system
wants to intercept and respond to the event. If so, or if the event
being reported is a null event, GetNextEvent returns a function result
of FALSE; a function result of TRUE means that your application should
handle the event itself. The Desk Manager intercepts the following
events:

    - activate and update events directed to a desk accessory

    - keyboard events if the currently active window belongs to a desk
      accessory

(note)
    In each case, the event is intercepted by the Desk
    Manager only if the desk accessory can handle that type
    of event; however, as a rule all desk accessories should
    be set up to handle activate, update, and keyboard
    events.

    The Desk Manager also intercepts disk-inserted events:  It attempts
to mount the volume on the disk by calling the File Manager function
MountVol. GetNextEvent will always return TRUE in this case, though,
so that your application can take any further appropriate action after
examining the result code returned by MountVol in the event message.
(See the Desk Manager and File Manager manuals for further details.)
GetNextEvent returns TRUE for all other non-null events (including all
mouse-down events, regardless of which window is active), leaving them
for your application to handle.

    GetNextEvent also makes the following processing happen, invisible
to your program:

   -If the "alarm" is set and the current time is the alarm time, the
    alarm goes off (a beep followed by blinking the title of the Apple
    menu). The user can set the alarm with the Alarm Clock desk
    accessory.

   -If the user holds down the Command and Shift keys while pressing a
    numeric key that has a special effect, that effect occurs. The
    standard such keys are 1 and 2 for ejecting the disk in the
    internal or external drive, and 3 and 4 for writing a snapshot of
    the screen to a MacPaint document or to the printer.

 (note)
    Advanced programmers can implement their own code to be
    executed in response to Command-Shift-number combinations
    (except for Command-Shift-l and 2, which can't be 
    changed). The code corresponding to a particular number
    must be a routine having no parameters, stored in a
    resource whose type is 'FKEY' and whose ID is the number.
    The system resource file contains code for the numbers 3
    and 4.
\ EventAvail
4
FUNCTION EventAvail (eventMask: INTEGER; VAR theEvent: EventRecord) :
    BOOLEAN;

    EventAvail works exactly the same as GetNextEvent except that if the
event is in the event queue, it's left there.

(note)
    An event returned by EventAvail will not be accessible
    later if in the meantime the queue becomes full and the
    event is discarded from it; since the events discarded
    are always the oldest ones in the queue, however, this
    will happen only in an unusually busy environment.
\ GetMouse
4
PROCEDURE GetMouse (VAR mouseLoc: Point);

    GetMouse returns the current mouse location in the mouseLoc
parameter. The location is given in the local coordinate system of the
current grafPort (which might be, for example, the currently active
window). Notice that this differs from the mouse location stored in the
where field of an event record; that location is always in global
coordinates.
\ Button
4
FUNCTION Button : BOOLEAN;

    The Button function returns TRUE if the mouse button is currently
down, and FALSE if it isn't.
\ Stilldown
4
FUNCTION StillDown : BOOLEAN;

    Usually called after a mouse-down event, StillDown tests whether the
mouse button is still down. It returns TRUE if the button is currently
down and there are no more mouse events pending in the event queue.
This is a true test of whether the button is still down from the
original press--unlike Button (above), which returns TRUE whenever the
button is currently down, even it ift has been released and pressed
again since the original mouse-down event.
\ WaitMouseUp
4
FUNCTION WaitMouseUp ) BOOLEAN;

    WaitMouseUp works exactly the same as StillDown (above), excent that
if the button is not still down from the original press, WaitMouseUp
removes the preceding mouse-up event before returning FALSE. If, for
instance, your application attaches some special significance both to
mouse double-clicks and to mouse-up events, this function would allow
your application to recognize a double-click without being confused by
the intervening mouse-up.
\ GetKeys
4
PROCEDUREGetKeys (VAR theKeys: KeyMap);

    GetKeys reads the current state of the keyboard (and keypad, if any)
and returns it in the form of a keyMap:

    TYPE KeyMap = PACKED ARRAY [¯..127] OF BOOLEAN;

    Each key on the keyboard or keypad corresponds to an element in the
keyMap. The index into the keyMap for a particular key is the same as
the key code for that key. (The key codes are shown in Figure 3
above.)  The keyMap element is TRUE if the corresponding key is down
and FALSE if it isn't. The maximum number of keys that can be down 
simultaneously is two character keys plus any combination of the four
modifier keys.
\ TickCount
4
FUNCTION TickCount : LONGINT;

    TickCount returns the current number of ticks (sixtieths of a
second) since the system was last started up.
\ GetDblTime
4
FUNCTION GetDblTime : LONGINT; [No trap macro]

    GetDblTime returns the suggested maximum difference (in ticks) that
should exist between the times of a mouse-up event and a mouse-down
event for those two mouse clicks to be considered a double-click. The
user can adjust this value by means of the Control Panel desk
accessory.
\ GetCaretTime
4
FUNCTION GetCaretTime : LONGINT; [No trap macro]

    GetCareTime returns the time (in ticks) between blinks of the
"caret" (usually a vertical bar) marking an insertion point in editable
text. If you aren't using TextEdit, you'll need to cause the caret to
blink yourself; on every pass through your program's main event loop,
you should check this value against the elapsed time since the last
blink of the caret. The user can adjust this value by means of the
Control Panel desk accessory.
\ InitWindows
5
PROCEDURE InitWindows;

    InitWindows initializes the Window Manager. It creates the Window
Manager port; you can get a pointer to this port with the GetWMgrPort
procedure. InitWindows draws the desktop and the (empty menu bar.
Call this procedure once berore all other Window Manager routines.

(note)
    InitWindows creates the Window Manager port as a
    nonrelocatable block in the application heap. For
    information on how this may affect your application's use
    of memory, see the Memory Manager manual. ***(A section
    on how to survive with limited memory will be added to
    that manual.) ***
\ GetWMgrPort
5
PROCEDURE GetWMgrPort (VAR wPort:  GrafPtr);

    GetWMgrPort returns in wPort a pointer to the Window Manager port.
\ NewWindow
5
FUNCTION NewWindow (wStorage: Ptr; boundsRect: Rect; title: Str255;
                    visible: BOOLEAN; procID: Integer;behind: WindowPtr;
                    goAway Flag: BOOLEAN; refCon: LongInt) : WindowPtr;

    NewWindow creates a window as specified by its parameters, adds it
to the window list, and returns a windowPtr to the new window. It
allocates space for the structure and content regions of the window and
asks the window definition function to calculate those regions.

    WStorage is a pointer to where to store the window record. For
example, if you've declared the variable wRecord of type WindowRecord,
you can pass @wRecord as the first parameter to NewWindow. If you pass
NIL for wStorage, the window record will be allocated on the heap; in
that case, though, the record will be nonrelocatable, and so you risk
ending up with a fragmented heap. You should therefore not pass NIL
for wStorage unless your program has an unusually large amount of
memory available or has been set up to dispose of windows dynamically.
Even then, you should avoid passing NIL for wStorage if there's no 
limit to the number of windows that your application can open. ***
(Some of this may be moved to the Memory Manager manual when that
manual is updated to have a section on how to survive with limited
memory.) ***

    BoundsRect, a rectangle given in global coordinates, determines the
window's size and location. It becomes the portRect of the window's
grafPort; note, however, that the portRect is in local coordinates.
New Window makes the QuickDraw call SetOrigin(¯,¯), so that the top left
corner of the portRect will be (¯,¯).

(note)
    The bitMap, pen pattern, and other characteristics of the
    window's grafPort are the same as the default values set
    by the OpenPort procedure in QuickDraw, except for the
    character font, which is set to the application font
    rather than the system font. Note, however, that the
    SetOrigin(¯,¯) call changes the coordinates of the
    grafPort's portBits.bounds and visRgn as well as its 
    PortRect.

    Title is the window's title. If the title of a document window is 
longer than will fit in the title bar, only as much of the beginning of
the title as will fit is displayed.

    If the visible parameter is TRUE, NewWindow draws the window. First
it calls the window definition function to draw the window frame; if
goAwayFlag is also TRUE and the window is frontmost (as specified by
the behind parameter, below), it draws a go-away region in the frame.
Then it generates an update event for the entire window contents.

    ProcID is the window definition ID, which leads to the window
definition function for this type of window. The window definition IDs
for the predefined types of windows are listed above under "Windows and 
Resources". Window definition IDs for windows of your own design are 
discussed later under "Defining Your Own Windows".

    The behind parameter determines the window's plane. The new window
is inserted in back of the window pointed to by this parameter. To put
the new window behind all other windows, use behind=NIL. To place it
in front of all other windows, use behind=POINTER(-1); in this case,
NewWindow will unhighlight the previously active window, highlight the
window being created, and generate appropriate activate events.

    RefCon is the window's reference value, set and used only by your 
application.

    NewWindow also sets the window class in the window record to
indicate that the window was created directly by the application.
\ GetNewWindow
5
FUNCTION GetNewWindow (ID: INTEGER; wStorage: Ptr; behind:
                        WindowPtr) : WindowPtr;

    Like NewWindow (above), GetNewWindow creates a window as specified
by its parameters, adds it to the window list, and returns a windowPtr
to the new window. The only difference between the two functions is
that instead of having the parameters boundsRect, title, visible,
procId, goAwayFlag, and refCon, GetNewWindow has a single windowID
parameter, where windowID is the resource ID of a window template that
supplies the same information as those parameters. The wStorage and
behind parameters of GetNewWindow have the same meaning as in NewWindow.
\ CloseWindow
5
PROCEDURE CloseWindow (theWindow: WindowPtr);

    CloseWindow removes the given window from the screen and deletes it
from the window list. It releases the memory occupied by all data
structures associated with the window, but not the memory taken up by
the window record itself. Call this procedure when you're done with a 
window if you supplied NewWindow or GetNewWindow a pointer to the
window storage (in the wStorage parameter) when you created the window.

    Any update events for the window are discarded. If the window was
the frontmost window and there was another window behind it, the latter
window is highlighted and an appropriate activate event is generated.
\ DisposeWindow
5
PROCEDURE DisposeWindow (theWindow: WindowPtr);

    DisposeWindow calls CloseWindow (above) and then releases the memory
occupied by the window record. Call this procedure when you're done 
with a window if you let the window record be allocated on the heap
when you created the window (by passing NIL as the wStorage parameter
to NewWindow or GetNewWindow).
\ SetWTitle
5
PROCEDURE SetWTitle (theWindow: WindowPtr; title: Str255);

    SetWTitle sets the Window's title to the given string, performing
any necessary redrawing of the window frame.
\ GetWTitle
5
PROCEDURE GetWTitle (theWindow: WindowPtr; VAR title: Str255);

    GetWTitle returns theWindow's title as the value of the title
parameter.
\ SelectWindow
5
PROCEDURE SelectWindow (theWindow: WindowPtr);

    SelectWindow makes theWindow the active window as follows:  it
unhighlights the previously active window, brings theWindow in front of
all other windows, highlights theWindow, and generates the appropriate
activate events. Call this procedure if there's a mouse-down event in 
the content region of an inactive window.
\ HideWindow
PROCEDURE HideWindow (theWindow: WindowPtr);

    HideWindow makes theWindow invisible. If theWindow is the frontmost
window and there's a window behind it, HideWindow also unhighlights 
theWindow, brings the window behind it to the front, highlights that
window, and generates appropriate activate events (se Figure 6). If
theWindow is already invisible, HideWindow has no effect.
\ ShowWindow
5
PROCEDURE ShowWindow (theWindow: WindowPtr);

    ShowWindow makes theWindow visible. It does not change the front-to-
back ordering of the windows. Remember that if you previously hid the
frontmost window with HideWindow, HideWindow will have brought the
window behind it to the front; so if you then do a ShowWindow of the
window you hid, it will no longer be frontmost (see Figure 6 above).
If the Window is already visible, ShowWindow has no effect.

(note)
    Although it's inadvisable, you can create a situation 
    where the frontmost window is invisible. If you do a
    ShowWindow of such a window, it will highlight the window
    if it's not already highlighted and will generate an 
    activate event to force this window from inactive to
    active.
\ ShowHide
5
PROCEDURE ShowHide (theWindow: WindowPtr; showFlag: (BOOLEAN);

    If showFlag is FALSE, ShowHide makes theWindow invisible if it's not
already invisible and has no effect if it is already invisible. If
showFlag is TRUE, ShowHide makes the Window visible if it's not already
visible and has no effect if it is already visible. Unlike HideWindow
and ShowWindow, ShowHide never changes the highlighting or front-to-
back ordering of windows or generates activates events.

(warning)
    Use this procedure carefully, and only in special
    circumstances where you need more control than allowed by
    HideWindow and ShowWindow.
\ HiliteWindow
5
PROCEDURE HiliteWindow (theWindow: WindowPtr; fHilite: BOOLEAN);

    If fHilite isTRUE, this procedure highlights theWindow if it's not
already highlighted and has no effect if it is highlighted. If fHilite
is FALSE, HiliteWindow unhighlights theWindow if it is highlighted and
has no effect if it's not highlighted. The exact way a window is 
highlighted depdnds on its window definition function.

    Normally you won't have to call this procedure, since you should
call SelectWindow to make a window active, and SelectWindow takes care
of the necessary highlighting changes. Highlighting a window that isn't 
the active window is contrary to the Macintosh User Interface
Guidelines.
\ BringToFront
5
PROCEDURE BringToFront (theWindow: WindowPtr);

    BringToFront brings theWindow to the front of all other windows and
redraws the window as necessary. Normally you won't have to call this 
procedure, since you should call SelectWindow to make a window active,
and SelectWindow takes care of bringing the window to the front. If
you do call BringToFront, however, remember to call HiliteWindow to
make the necessary highlighting changes.
\ SendBehind
5
PROCEDURE SendBehind (theWindow: WindowPtr; behindWindow: WindowPtr);

    SendBehind sends theWindow behind behindWindow, redrawing any
exposed windows. If behindWindow is NIL, it sends theWindow behind all
other windows. If theWindow is the active window, it unhighlights the
Window, highlights the new active window, and generates the appropriate
activate events.

(warning)
    Do not use SendBehind to deactivate a previously active
    window. Calling SelectWindow to make a window active
    takes care of deactivating the previously active window.

(note)
    If you're moving theWindow closer to the front (that is,
    if it's initially even farther behind behind(Window), you
    must make the following calls after calling SendBehind:

        wPeek := POINTER(theWindow);
        PaintOne(wPeek, wPeek^.strucRgn);
        CalcVis(wPeek)

    PaintOne and CalcVis are described below under "Low'Level
    Routines".
\ FrontWindow
5
FUNCTION FrontWindow : WindowPtr;

    FrontWindow returns a pointer to the first visible window in the
window list (that is, the active window). If there are no visible
windows, it returns NIL.
\ DrawGrowIcon
5
PROCEDURE DrawGrowIcon (theWindow: WindowPtr).

    Call DrawGrowIcon in responce to an update or activate event
involving a window that contains a size box in its content region. If
theWindow is active (highlighted), DrawGrowIcon draws the size box;
otherwise, it draws whatever is appropriate to show that thewindow
temporily cannot be sized. The exact appearance and location of what's
drawn depend on the window definition function. For an active document
window, DrawGrowIcon draws the size box icon in the bottom right corner
of the portRect of the window's grafPort, along with the lines
delimiting the size box and scroll bar areas (15 pixels in from the
right edge and bottom of the portRect). It doesn't erase the scroll
bar areas, so if the window doesn't contain scroll bars you should 
erase those areas yourself after the window's size changes. For an 
inactive document window, DrawGrowIcon draws only the delimiting lines
(again, without erasing anything).
\ FindWindow
5
FUNCTION FindWindow (thePt: Point; VAR whichWindow: WindowPtr) :
    INTEGER;

    When a mouse-down event occurs, the application should call
FindWindow with thePt equal to the point where the mouse button was
pressed (in global coordinates, as stored in the where field of the
event record). FindWindow tells which part of which window, if any, the
mouse button was pressed in. If it was pressed in a window, the
whichWindow parameter is set to the window pointer; otherwise, it's set
to NIL. The integer returned by FindWindow is one of the following
predefined constants:

CONST inDesk      = ¯;  {none of the following}
      InMenuBar   = 1;  {in menu bar}
      inSysWindow = 2;  {in system window}
      inContent   = 3;  {in content region (except grow, if active)}
      inDrag      = 4;  {in drag region}
      inGrow      = 5;  {in grow region (active window only)}
      inGoAway    = 6;  {in go-away region (active window only)}
      inZoomin    = 7;
      inZoomOut   = 8;

    InDesk usually means that the mouse button was pressed on the
desktop, outside the menu bar or any windows; however, it may also mean
that the mouse button was pressed inside a window frame but not in the
drag region or go-away region of the window. Usually one of the last
four values is returned for windows created by the application.

    If the window is a documentProc type of window that doesn't contain
a size box, the application should treat  inGrow the same as inContent;
if it's a noGrowDocProc type of window, FindWindow will never return 
inGrow for that window. If the window is a documentProc, noGrowDocProc,
or rDocProc type of window with no close box, FindWindow will never
return inGoAway for that window.
\ TrackGoAway
5
FUNCTION TrackGoAway (theWindow: WindowPtr; thePt: Point) : BOOLEAN;

    When there's a mouse-down event in the go-away region of theWindow,
the application should call TrackGoAway with thePt equal to the point
where the mouse button was pressed (in global coordinates, as stored in
the where field of the event record). TrackGoAway keeps control until
the mouse button is released, highlighting the go-away region as long as
the mouse position remains inside it, and unhighlighting it when the
mouse moves outside it. The exact way a window's go-away region is 
highlighted depends on its window definition function; the highlighting
of a document window's close box is illustrated in Figure 7. When the 
mouse  button is released, TrackGoAway unhighlights the go-away region
and returns TRUE if the mouse is inside the go-away region or FALSE if
it's outside the region (in which case the application should do
nothing).
\ MoveWindow
5
PROCEDURE MoveWindow (theWindow: WindowPtr; hGlobal,vGlobal: INTEGER;
    front: BOOLEAN);

    MoveWindow moves theWindow to another part of the screen, without
affecting its size or plane.  The top left corner of the portRect of
the window's grafPort is moved to the screen point indicated by the 
global coordinates hGlobal and vGlobal. The local coordinates of the
top left corner remain the same; MoveWindow saves those coordinates
before moving the window and calls the QuickDraw procedure SetOrigin to
restore them before returning. If the front parameter is TRUE and
theWindow isn't the active window, MoveWindow makes it the active 
window by calling SelectWindow(theWindow).
\ DragWindow
5
PROCEDURE DragWindow (theWindow: WindowPtr; startPt: Point; boundsRect:
    Rect);

    When there's a mouse-down event in the drag region of theWinow, the 
application should call DragWindow with StartPt equal to the point
where the mouse button was pressed (in global coordinates, as stored in
the where field of the event record). DragWindow pulls a gray outline
of theWindow around, following the movements of the mouse until the
button is released. When the mouse button is released, DragWindow
calls MoveWindow to move theWindow to the location to which it was
dragged. If theWindow is not the active window and the Command key was
not being held down, DragWindow makes it the active window (by passing
TRUE for the front parameter when calling MoveWindow).

    BoundsRect is also given in global coordinates. If the mouse button
is released when the mouse position is outside the limits of boundsRect,
DragWindow returns without moving theWindow or making it the active
window. For a document window, boundsRect typically will be four
pixels in from the menu bar and from the other edges of the screen, to
ensure that there won't be less than a four-pixel-square area of the 
title bar visible on the screen.
\ GrowWindow
5
FUNCTION GrowWindow (theWindow: WindowPtr; startPt: Point; sizeRect:
    Rect) : LongInt;

    When there's a mouse-down event in the grow region of theWindow, the 
application should call GrowWindow with startPt equal to the point
where the mouse button was pressed (in global ccoordinates, as stored in
the where field of the event record). GrowWindow pulls a GROW IMAGE of
the window around, following the movements of the mouse until the
button is released. The grow image for a document window is a gray
outline of the entire window and also the lines delimiting the title
bar, size box, and scroll bar areas; Figure 8 illustrates this for a
document window containing a size box and scroll bars, but the grow
image would be the same even if the window contained no size box, one
scroll bar, or no scroll bars. In general, the grow image is defined
in the window definition function and is whatever is appropriate to
show that the window's size will change. 

    The application should subsequently call SizeWindow (see below) to
change the portRect of the window's grafPort to the new one outlined by 
the grow image. The sizeRect parameter specifies limits, in pixels, on
the vertical and horizontal measurements of what will be the new
portRect. SizeRect.top is the minimum vertical measurement,
sizeRect.left is the minimum horizontal measurement, sizeRect.bottom is
the maximum vertical measurement, and sizeRect.right is the maximum
horizontal measurement.

    GrowWindow returns the actual size for the new portRect as outlined
by the grow image when the mouse button is released. The high-order
word of the LongInt is the vertical measurement in pixels and the
low-order word is the horizontal measurement. A return value of ¯
indicates that the size is the same as that of the current portRect.

(note)
    The Toolbox Utility function HiWord takes a long integer
    as a parameter and returns an integer equal to its high-
    order word; the function LoWord returns the low-order
    word.
\ SizeWindow
5
PROCEDURE SizeWindow (theWindow: WindowPtr; w,h: INTEGER; fUpdate:
    BOOLEAN);

    SizeWindow enlarges or shrinks the portRect of the Window's grafPort
to the width and height specified by w and h, or does nothing if w and h
are ¯. The window's position on the screen does not change. The new 
window frame is drawn; if the width of a document window changes, the
title is again centered in the title bar, or is truncated at its end if
it no longer fits. If fUpdate is TRUE, SizeWindow accumulates any
newly created area of the content region into the update region (see
figure 9);  normally this is what you'll want. If you pass FALSE for 
fUpdate, you're responsible for the update region maintenance yourself.
For more information, see InvalRect and ValidRect below.

(note)
    You should change the window's size only when the user 
    has done something specific to make it change.
\ InvalRect
5
PROCEDURE InvalRect (badRect: Rect);

    InvalRect accumulates the given rectangle into the update region of
the window whose grafPort is the current port. This tells the Window
Manager that the rectangle has changed and must be updated. The
rectangle lies within the window's content region and is given in the 
local coordinates.

    For example, this procedure is useful when you're calling SizeWindow 
(described above) for a document window that contains a size box or
scroll bars. Suppose yuou're going to call SizeWindow with 
fUpdate=TRUE. If the window is enlarged as shown in Figure 8 above,
you'll want not only the newly created part of the content region to be 
updated, but also the two rectangular areas containing the (former)
size box and scroll bars; before calling SizeWindow, you can call
InvalRect twice to accumulate those areas into the update region. In
case the window is made smaller, you'll want the new size box and 
scroll bar areas to be updated, and so can similarly call InvalRect for
those areas after calling SizeWindow. See Figure 1¯ for an
iillustration of this type of update region maintenance.

    As another example, suppose your application scrolls up text in a
document window and wants to show new text added at the bottom of the
window. You can cause the added text to be redrawn by accumulating
that area into the update region with InvalRect.
\ InvalRgn
5
PROCEDURE InvalRgn (badRgn: RgnHandle);

    InvalRgn is the same as InvalRect (above) but for a region that has
changed rather than a rectangle.
\ ValidRect
5
PROCEDURE ValidRect (goodRect: Rect);

    ValidRect removes goodRect from the update region of the window
whose grafPort is the current port. This tells the Window Manager that
the application has already drawn the rectangle and to cancel any
updates accumulated for that area. The rectangle lies within the
window's content region and is given in local coordinates. Using
ValidRect results in better performance and less redundant redrawing in
the window.

    For example, suppose you've called SizeWindow (described above) with 
fUpdate=TRUE for a document window that contains a size box or scroll
bars. Depending on the dimensions of the newly sized window, the new
size box and scroll bar areas may or may not have been accumulated into
the window's update region. After calling SizeWindow, you can redraw
the size box or scroll bars immediately and then call ValidRect for the
areas they occupy in case they were in fact accumulated into the update
region; this will avoid redundant drawing.
\ ValidRgn
5
PROCEDURE ValidRgn (goodRgn: RgnHandle);

    ValidRgn is the same as ValidRect (above) but for a region that has
been drawn rather than a rectangle.
\ BeginUpdate
5
PROCEDURE BeginUpdate (theWindow: WindowPtr);

    Call BeginUpdate when an update event occurs for theWindow.
BeginUpdate replaces the visRgn of the window's grafPort with the 
intersection of the visRgn and the update region and then sets the
window's update region to the empty region. You would then usually
draw the entire content region, though it suffices to draw only the
visRgn; in either case, only the parts of the window that require
updating will actually be drwn on the screen. Every call to
BeginUpdate must be balanced by a call to EndUpdate. (See below, and
see "How a Window is Drawn".)
\ EndUpdate
5
PROCEDURE EndUpdate (theWindow: WindowPtr);

    Call EndUpdate to restore the normal visRgn of theWindow's grafPort, 
which was changed by BeginUpdate as described above.
\ SetWRefCon
5
PROCEDURESetWRefCon (theWindow: WindowPtr; data: LongInt);

    SetWRefCon sets theWindow's reference value to the given data.
\ GetWRefCon
5
FUNCTION GetWRefCon (theWindow: WindowPtr) : LongInt;

    GetWRefCon returns theWindow's current reference value. 
\ SetWindowPic
5
PROCEDURE SetWindowPic (theWindow: WindowPtr; pic: PicHandle);

    SetWindowPic stores the given picture handle in the window record
for theWindow, so that when theWindow's contents are to be drawn, the 
Window Manager will draw this picture rather than generate an update
event.
\ GetWindowPic
5
FUNCTION GetWindowPic (theWindow: WindowPtr) : PicHandle;

    GetWindowPic returns the handle to the picture that draws
theWindow's contents, previously stored with SetWindowPic (above).
\ PinRect
5
FUNCTION PinRect (theRect: Rect; thePt: Point) : LongInt;

    PinRect "pins" thePt inside theRect: The high-order word of the
function result is the vertical coordinate of thePt or, if thePt lies
above or below theRect, the vertical coordinate of the top or bottom of
theRect, respectively. The low-order word of the function result is
the horizontal coordinate of thePt or, if thePt lies to the left or
right of theRect, the horizontal coordinate of the left or right edge
of theRect.
\ DragGrayRgn
5
FUNCTION DragGrayRgn (theRgn: RgnHandle; startPt: Point;
    limitRect,slopRect: Rect; axis: INTEGER; actionProc:
    ProcPtr : LongInt;

    Called when the mouse button is down inside theRgn, DragGrayRgn
pulls a gray outline of the region around, following the movements of
the mouse until the button is released. DragWindow calls this function
before actually moving the window, and the Control Manager routine
DragControl similarly calls it for controls. You can call it yourself
to pull around the outline of any region, and then use the information
it returns to determine where to move the region.

    The startPt parameter is assumed to be the point where the mouse
button was orignally pressed, in the local coordinates of the current
LimitRect and slopRect are also in the local coordinates of the current
grafPort. To explain these parameters, the concept of "offset point"
must be introduced: this is the point whose vertical and horizontal
offsets from the top left corner of the region's enclosing rectangle 
are the same as those of startPt. Initially the offset point is the
same as the mouse position, but they may differ, depending on where the
user moves the mouse. DragGrayRgn will never move the offset point
outside limitRect; this limits the travel of the region's outline (but
not the movements of the mouse). SlopRect, which should completely
enclose limitRect, allows the user some "slop" in moving the mouse.
DragGrayRgn's behavior while tracking the mouse depends on the position 
of the mouse with respect to these two rectangles

   - when the mouse is inside limitRect, the region's outline follows
     it normally. If the mouse button is released there, the region
     should be moved to the mouse position.

   - When the mouse is outside limitRect but inside slopRect,
     DragGrayRgn "pins" the offset point to the edge of limitRect. If
     the mouse button is released there, the region should be moved to
     this pinned location.

   - When the mouse is outside slopRect, the outline disappears from
     screen, but DragGrayRgn continues to follow the mouse; if it
     moves back into slopRect, the outline reappears. If the mouse
     button is released outside slopRect, the region should not be
     moved from its original position.

    Figure 11 illustrates what happens when the mouse is moved outside
limitRect but inside slopRect, for a rectangular region. The offset
point is pinned as the mouse position moves on.

    If the mouse button is released outside slopRect, DragGrayRgn
returns -32768 ($8¯¯¯); otherwise, the high-order word of the value
returned contains the vertical coordinate of the ending mouse point
minus that of startPt and the low-order word contains the difference
between the horizontal coordinates.

    The axis parameter allows you to constrain the outline's motion to
only one axis. It has one of the following values:

    CONST noConstraint = ¯;     {no constraint}
          hAxis Only   = 1;     {horizontal axis only}
          vAxis Only   = 2;     {vertical axis only}

    If noaxis constraint is in effect, the outline will follow the
mouse's movements along the specified axis only, ignoring motion along
the other axis. With or without an axis constraint, the mouse must
still be inside the slop rectangle for the outline to appear at all.

    The actionProc parameter is a pointer to a procedure that defines
some action to be performed repeatedly for as long as the user holds
down the mouse button; the procedure should have no parameters. If
actionProc is NIL, DragGrayRgn simply retains control until the mouse
button is released, performing no action while the mouse button is
down.
\ CheckUpdate
5
FUNCTION CheckUpdate (VAR the Event: EventRecord) : BOOLEAN;

    CheckUpdate is called by the Toolbox Event Manager. From the front
to the back in the window list, it looks for a visible window that needs
updating (that is, whose update region is not empty). If it finds one
whose window record contains a picture handle, it draws the picture
(doing all the necessary region manipulation) and looks for the next
visible window that needs updating. If it ever finds one whose window
record doesn't contain a picture handle, it stores an update event for 
that window in theEvent and returns TRUE. If it never finds such a
window, it returns FALSE.
\ ClipAbove
5
PROCEDURE ClipAbove (window: WindowPeek);

    ClipAbove sets the clipRgn of the Window Manager port to be the
desktop (global variable grayRgn) intersected with the current clipRgn,
minus the structure regions of all the windows above the given window.
\ SaveOld
5
PROCEDURE SaveOld (window: WindowPeek);

    SaveOld saves the given window's current structure region and
content region for the DrawNew operation (see below). It must be
balanced by a subsequent call to DrawNew.
\ DrawNew
5
PROCEDURE DrawNew (window: WindowPeek; update: BOOLEAN);

    If the update parameter is TRUE, DrawNew updates the area.

    (oldStruct XOR newStruct) UNION oldContent XOR newContent)

    where oldStruct and oldContent are the structure and content regions
saved by the SaveOld procedures, and newStruct and newContent are the
current structure and content regions. It paints the area white and
adds it to the window's update region. If update is FALSE, it only
paints the area white.

(warning)
    SaveOld and DrawNew are not nestable.
\ PaintOne
5
PROCEDURE PaintOne (window: WindowPeek; clobberedRgn: RgnHandle);

    PaintOne "paints" the given window, clipped to clobberedRgn and all
windows above it: it draws the window frame and, if some content is
exposed, paints the exposed area white and adds it to the window's 
update region. If the window parameter is NIL, the window is the
desktop and so is painted gray.
\ PaintBehind
5
PROCEDURE PaintBehind (startWindow: WindowPeek; clobberedRgn:
    RgnHandle);

    PaintBehind calls PaintOne (above for startWindow and all the
windows behind startWindow, clipped to clobberedRgn.
\ CalcVis
5
PROCEDURE CalcVis (window: WindowPeek);

    CalVis calculates the visRgn of the given window by starting with
its content region and subtracting the structure region of each window
in front of it.
\ CalcVisBehind
5
PROCEDURE CalcVisBehind (startWindow: WindowPeek; clobberedRgn:
    RegHandle;

    CalcVisBehind calculates the visRgns of start Window and all windows
behind startWindow that intersect with clobberedRgn. It's called after 
PaintBehind (see  above).
\ TrackBox
5
FUNCTION TrackBox (theWindow: WindowPtr; thePt: Point;
                    partCode: INTEGER) : BOOLEAN;

    When thereÕs a mouse-down event in the zoom-window box of theWindow,
the application should call TrackBox with thePt equal to the point
where the mouse button was pressed (in global coordinates, as stored
in the where field of the event record). The partCode parameter
contains the constant (either inZoomIn or inZoomOut) returned by
FindWindow. TrackBox keeps control until the mouse button
is released; it highlights the zoom-window box in the same way as
a windowÕs close box is highlighted. When the mouse button is released,
TrackBox unhighlights the zoom-window box and returns TRUE if
the mouse is inside the zoom-window box or FALSE if itÕs outside
the box (in which case the application should do nothing).
\ ZoomWindow
5
PROCEDURE ZoomWindow (theWindow: WindowPtr;
                        partCode: INTEGER; front: BOOLEAN);

    Call ZoomWindow after a call to TrackBox that returns TRUE.
The partCode parameter contains the constant (either inZoomIn or
inZoomOut) returned by FindWindow. The window will be zoomed either
out or in, depending on the state of the window specified by partCode.
If the window is already in the state specified by partCode, ZoomWindow
does nothing. If the front parameter is TRUE, the window will be
brought to the front; otherwise, the window is left where it is.
(This means a window can be zoomed without necessarily becoming
the active window.)

    For best results, call the QuickDraw procedure EraseRect with the
portRect field of theWindowÕs grafPort before calling ZoomWindow.

Warning:  Using the QuickDraw procedure SetPort, set thePort to the
          windowÕs port before calling ZoomWindow.

Note:     ZoomWindow is in no way tied to the TrackBox function and
          could just as easily be called in response to a selection
          from a menu.
\ NewControl
6
FUNCTION NewControl (theWindow: WindowPtr; boundsRect: Rect; title:
                    Str255; visible: BOOLEAN; value: INTEGER;
                    min,max: INTEGER; procID: INTEGER; refCon: LongInt)
                    : ControlHandle;


    NewControl creates a control, adds it to the beginning of
theWindow's control list, and returns a handle to the new control. The
values passed as parameters are stored in the corresponding fields of
the control record, as described below. The field that determines
highlighting is set to ¯ (no highlighting) and the pointer to the
default action procedure is set to NIL (none).

(note)
    The control definition function may do additional
    initialization, including changing any of the fields of
    the control record. The only standard control for which
    additional initialization is done is the scroll bar; its
    control definition function allocates space for a region
    to hold the thumb and stores the region handle in the
    contrlData field of the control record.

    TheWindow is the window the new control will belong to. All
coordinates pertaining to the control will be interpreted in this
window's local coordinate system.

    BoundsRect, given in theWindow's local coordinates, is the rectangle 
that encloses the control and thus determines its size and location.
Note the following about the enclosing rectangle for the standard
controls:

      - Simple buttons are drawn to fit the rectangle exactly. (The
        control definition function calls the QuickDraw procedure
    FrameRoundRect.)  To allow for the tallest characters in the
    system font, there should be at least a 2¯-point difference
    between the top and bottom coordinates of the rectangle.

      - For check boxes and radio buttons, there should be at least a
    16-point difference between the top and bottom coordinates.

      - By convention, scroll bars are 16 pixels wide, so there should be
    a 16-point difference between the left and right (or top and
    bottom) coordinates. If there isn't, the scroll bar will be 
    scaled to fit the rectangle.

    Title is the control's title, if any (if none, you can just pass the 
empty string as the title). Be sure the title will fit in the
control's enclosing rectangle; if it won't, it will be truncated on the
right for check boxes and radio buttons, or centered and truncated on
both ends for simple buttons.

    If the visible parameter is TRUE, NewControl draws the control.

(note)
    It does NOT use the standard window updating mechanism,
    but instead draws the control immediately in the window.

    The min and max parameters define the control's range of possible 
settings; the value parameter gives the initial setting. For controls
that don't retain a setting, such as buttons, the values you supply for 
these parameters will be stored in the control record but will never be
used. So it doesn't matter what values you give for those controls--¯
for all three parameters will do. For controls that just retain an
on-or-off setting, such as check boxes or radio buttons, min should be
¯ (meaning the control is off) and max should be 1 (meaning it's on).
For dials, you can specify whatever values are appropriate for min,
max, and value.

    ProcID is the control definition ID, which leads to the control
definition function for this type of control. The control definition
IDs for the standard control types are listed above under "Controls and 
Resources". Control definition IDs for custom control types are 
discussed later under "Defining Your Own Controls".

    RefCon is the control's reference value, set and used only by your 
application.
\ GetNewControl
6
FUNCTION GetNewControl (controlID: INTEGER; theWindow: WindowPtr)
                        : ControlHandle;

    GetNewControl creates a control from a control template stored in a
resource file, adds it to the beginning of theWindow's control list, 
and returns a handle to the new control. ControlID is the resource ID
of the template. GetNewControl works exactly the same as NewControl
(above), except thatt it gets the initial values for the new control's
fields from the specified control template instead of accepting them as
parameters.
\ DisposeControl
6
PROCEDURE DisposeControl (theControl: ControlHandle);

    DisposeControl removes theControl from the screen, deletes it from
its window's control list, and releases the memory occupied by the
control record and all data structures associated with the control.
\ KillControls
6
PROCEDURE KillControls (theWindow: WindowPtr);

    KillControls disposes of all controls associated with theWindow by
calling DisposeControl (above) for each.
\ SetCTitle
6
PROCEDURE SetCTitle (theControl: ControlHandle; title: Str255);

    SetCTitle sets theControl's title to the given string and redraws
the control.
\ GetCTitle
6
PROCEDURE GetCTitle (theControl: ControlHandle; VAR title: Str255);

    GetCTitle returns theControl's title as the value of the title 
parameter.
\ HideControl
6
PROCEDURE HideControl (theControl: ControlHandle);

    HideControl makes theControl invisible. It fills the region the
control occupies within its window with the background pattern of the
window's grafPort. It also adds the control's enclosing rectangle to
the window's update region, so that anything else that was previously 
obscured by the control will reappear on the screen. If the control is
already invisible, HideControl has no effect.
\ ShowControl
6
PROCEDURE ShowControl (theControl: ControlHandle);

    ShowControl makes theControl visible. The control is drawn in its
window but may be completely or partially obscured by overlapping
windows or other objects. If the control is already visible,
ShowControl has no effect.
\ DrawControls
6
PROCEDURE DrawControls (theWindow: WindowPtr);

    DrawControls draws all controls currently visible in theWindow. The
controls are drawn in reverse order of creation; thus in case of
overlap the earliest-created controls appear frontmost in the window.

(note)
    WindowManager routines such as SelectWindow, ShowWindow,
    and BringToFront do not automatically call DrawControls
    to display the window's controls. They just add the 
    appropriate regions to the window's update region, 
    generating an update event. Your program should always
    call DrawControls explicitly upon receiving an update
    event for a window that contains controls.
\ HiliteControl
6
PROCEDURE HiliteControl (theControl: ControlHandle; hiliteState:
                        INTEGER);

    HiliteControl changes the way theControl is highlighted. HiliteState
is an integer between ¯ and 255;

       - A value of ¯ means no highlighting.

       - A value between 1 and 253 is interpreted as a part code
         designating the part of the control to be highlighted.

       - A value of 254 or 255 means that the control is to be made
         inactive and highlighted accordingly. Usually you'll want to
         use 254, because it enables you to detect when the mouse button
         was pressed in the inactive control as opposed to not in any
         control;
         for more information, see FindControl under "Mouse Location"
         below.

    Hilite Control calls the control definition function to redraw the
control with its new highlighting.
\ TestControl
6
FUNCTION TestControl (theControl: ControlHandle; thePoint: Point)
                        :  INTEGER;

    If theControl is visible and active, TestControl tests which part of
the control contains thePoint (in the local coordinates of the
control's window); it returns the corresponding part code, or ¯ if the 
point is outside the control. If the control is visible and inactive
with 254 highlighting, TestControl returns 254. If the control is
invisible, or inactive with 255 highlighting, TestControl returns ¯.
\ FindControl
6
FUNCTION FindControl (thePoint: Point; theWindow: WindowPtr; VAR
                        whichControl: ControlHandle) : INTEGER;

    When the Window Manager function FindWindow reports that the mouse
button was pressed in the content region of a window, and the window
contains controls, the application should call FindControl with
theWindow equal to the window pointer and thePoint equal to the point
where the mouse button was pressed (in the window's local coordinates).
FindControl tells which of the window's controls, if any, the mouse 
button was pressed in:

      - If it was pressed in a visible, active control, FindControl sets
        the whichControl parameter to the control handle and returns a
        part code identifying the part of the control that it was
        pressed in.

      - If it was pressed in a visible, inactive control with 254
        highlighting, FindControl sets whichControl to the control
        handle and returns 254 as its result.

      - If it was pressed in an invisible control, an inactive control
        with 255 highlighting, or not in any control, FindControl sets
        whichControl to NIL and returns ¯ as its result.

(warning)
    Notice that FindControl expects the mouse point in the
    window's local coordinates, whereas FindWindow expects it 
    in global coordinates. Always be sure to convert the
    point to local coordinates with the QuickDraw procedure
    GlobalToLocal before calling FindControl.

(note)
    FindControl also returns NIL for whichControl and ¯ as
    its result if the window is invisible or doesn't contain 
    the given point. In these cases, however, FindWindow
    wouldn't have returned this window in the first place, so 
    the situation should never arise.
\ TrackControl
6
FUNCTION TrackControl (theControl: ControlHandle; startPt: Point;
    actionProc: ProcPtr) : INTEGER;

    When the mouse button is pressed in a visible, active control, the
application should call TrackControl with theControl equal to the
control handle and startPt equal to the point where the mouse button
was pressed (in the local coordinates of the control's window).
TrackControl follows the movements of the mouse and responds in
whatever way is appropriate until the mouse button is released; the
exact response depends on the type of control and the part of the
control in which the mouse button was pressed. If highlighting is
appropriate, TrackControl does the highlighting, and undoes it before
returning. When the mouse button is released, TrackControl returns
with the part code if the mouse is in the same part of the control that
it was originally in, or with ¯ if not (in which case the application
should do nothing.

    If the mouse button was pressed in an indicator, TrackControl drags
a gray outline of it to follow the mouse (by calling the Window Manager
utility function DragGrayRgn). When the mouse button is released,
TrackControl calls the control definition function to reposition the
control's indicator. The control definition function for scroll bars 
responds by redrawing the thumb, calculating  the control's current 
setting based on the new relative position of the thumb, and storing
the current setting in the control record; for example, if the minimum
and maximum settings are  ¯ and 1¯, and the thumb is in the middle of
the scroll bar, 5 is stored as the current setting. The application
must then scroll to the corresponding relative position in the
document.

    TrackControl may take additional actions beyond highlighting the
control or dragging the indicator, depending on the value passed in the
actionProc parameter, as described below. Here you'll learn what to 
pass for the standard control types; for a custom control, what you
pass will depend on how the control is defined.

      - If actionProc is NIL, TrackControl performs no additional
        actions. This is appropriate for simple buttons, check boxes,
        radio buttons, and the thumb of a scroll bar.

      - ActionProc may be a pointer to an action procedure that defines
        some action to be performed repeatedly for as long as the user
        holds down the mouse button. (See below for details)

      - If actionProc is POINTER(-1), TrackControl looks in the control
        record for a pointer to the control's default action procedure. 
        If that field of the control record contains a procedure
        pointer, TrackControl uses the action procedure it points to; if
        the field contains POINTER(-1), TrackControl calls the control
        definition function to perform the necessary action. (If the
        field contains NIL, TrackControl does nothing.)

    The action procedure in the control definition function is described
in the section "Defining Your Own Controls". The following paragraphs
describe only the action procedure whose pointer is passed in the
actionProc parameter or stored in the control record.

    If the mouse button was pressed in an indicator, the action
procedure (if any) should have no parameters. This procedure must allow
for the fact that the mouse may not be inside the original control part.

    If the mouse button was pressed in a control part other than an
indicator, the action procedure should be of the form

    PROCEDURE MyAction (theControl: ControlHandle; partCode: INTEGER);

    In this case, TrackControl passes the control handle and the part
code to the action procedure. (It passes ¯ in the partCode parameter if
the mouse has moved outside the original control part.)  As an example
of this type of action procedure, consider what should happen when the
mouse button is pressed in a scroll arrow or paging region in a scroll
bar. For these cases, your action procedure should examine the part
code to determine exactly where the mouse button was pressed, scroll up
or down a line or page as appropriate, and call SetCt1Value to change
the control's setting and redraw the thumb.

(warning)
    Since it has a different number of parameters depending
    on whether the mouse button was pressed in an indicator
    or elsewhere, the action procedure you pass to
    TrackControl (or whose pointer you store in the control
    record) can be set up for only one case or the other. If
    you store a pointer to a default action procedure in a
    control record, be sure it will be used only when
    appropriate for that type of action procedure. The only
    way to specify actions in response to all mouse-down
    events in a control, regardless of whether they're in an 
    indicator, is via the control definition function.
\ MoveControl
6
PROCEDURE MoveControl (theControl: ControlHandle; h,v: INTEGER);

    MoveControl moves theControl to a new location within its window.
The top left corner of the control's enclosing rectangle is moved to the 
horizontal and vertical coordinates h and v (given in the local
coordinates of the control's window);  the bottom right corner is 
adjusted accordingly, to keep the size of the rectangle the same as
before. If the control is currently visible, it's hidden and then 
redrawn at its new location.

\ DragControl
6
PROCEDURE DragControl (theControl: ControlHandle; startPt: Point;
                        limitRect,slopRect: Rect; axis: INTEGER);

    Called with the mouse button down inside theControl, DragControl
pulls a gray outline of the control around the screen, following the
movements of the mouse until the button is released. When the mouse
button is released, DragControl calls MoveControl to move the control
to the location to which it was dragged.

(note)
    Before beginning to follow the mouse, DragControl calls
    the control definition function to allow it to do its own
    "custom dragging" if it chooses. If the definition
    function doesn't choose to do any custom dragging, 
    DragControl uses the default method of dragging described
    here.

    DragControl calls the Window Manager utility function DragGrayRgn
and then moves the control accordingly. The startPt, limitRect,
slopRect, and axis parameters have the same meaning as for DragGrayRgn.
These parameters are reviewed briefly below; see the description of
DragGrayRgn in the Window Manager manual for more details.

      - StartPt parameter is assumed to be the point where the mouse
        button was originally pressed, in the local coordinates of the
        control's window. 

      - LimitRect limits the travel of the control's outline, and should 
        normally coincide with or be contained within the window's
        content region.

      - SlopRect allows the user some "slop" in moving the mouse; it
        should completely enclose limitRect.

      - The axis parameter allows you to constrain the control's motion to
        only one axis. It has one of the following values:

    CONST noConstraint  =   ¯;  {no constraint}
          hAxis Only    =   1;  {horizontal axis only}
          vAxis Only    =   2;  {vertical axis only}
\ Size Control
6
PROCEDURE SizeControl (theControl: ControlHandle; w,h: INTEGER);

    SizeControl changes the size of theControl's enclosing rectangle.
The bottom right corner of the rectangle is adjusted to set the
rectangle's width and height to the number of pixels specified by w and
h; the position of the top left corner is not changed. If the control
is currently visible, it's hidden and then redrawn in its new size.
\ SetCtlValue
6
PROCEDURE SetCtlValue (theControl: ControlHandle; theValue: INTEGER);

    SetCtlValue sets theControl's current setting to theValue and
redraws the control to reflect the new setting. For check boxes and
radio buttons, the value 1 fills the control with the appropriate mark,
and ¯ clears it. For scroll bars, SetCtlValue redraws the thumb where
appropriate.

    If the specified value is out of range, it's forced to the nearest 
endpoint of the current range (that is, if theValue is less than the
minimum setting, SetCtlValue sets the current setting to the minimum;
if theValue is greater than the maximum setting, it sets the current
setting to the maximum.
\ GetCtlValue
6
FUNCTION GetCtlValue (theControl: ControlHandle) : INTEGER;

    GetCtlValue returns theControl's current setting. 
\ SetCtlMin
6
PROCEDURE SetCtlMin (theControl: ControlHandle; minValue: INTEGER;

    SetCtlMin sets theControl's minimum setting to minValue and redraws
the control to reflect the new range. If the control's current setting
is less than minValue, the setting is changed to the new minimum.
\ GetCtlMin
6
FUNCTION GetCtlMin (theControl: ControlHandle) : INTEGER;

    GetCtlMin returns theControl's minimum setting.
\ SetCtlMax
6
PROCEDURE SetCtlMax (theControl: ControlHandle; maxValue: INTEGER);

    SetCtlMax sets theControl maximum setting to maxValue and redraws
the control to reflect the new range. If maxValue is less than the
control's current setting, the setting is changed to the new maximum.
\ GetCtlMax
6
FUNCTION GetCtlMax (theControl: ControlHandle) : INTEGER;

    GetCtlMax returns theControl's maximum setting.
\ SetCRefCon
6
PROCEDURE SetCRefCon (theControl: ControlHandle; data: LongInt);

    SetCRefCon sets theControl's reference value to the given data.
\ GetCRefCon
6
FUNCTION GetCRefCon (theControl: ControlHandle) : LongInt;

    GetCRefCon returns theControl's current reference value.
\ SetCtlAction
6
PROCEDURE SetCtlAction (theControl: ControlHandle; actionProc:
                        ProcPtr);

    SetCtlAction sets theControl's default action procedure to
actionProc.
\ GetCtlAction
6
FUNCTION GetCtlAction (theControl: ControlHandle) : ProcPtr;

    GetCtlAction returns a pointer to theControl's default action 
procedure, if any. (It returns whatever is in that field of the
control record.)


The Control Definition Function
-------------------------------

    The control definition function may be written in Pascal or assembly
language; the only requirement is that its entry point must be at the
beginning. You can give your control definition function any name you
like. Here's how you would declare one named MyControl:

    FUNCTION MyControl (varCode: INTEGER; theControl; ControlHandle;
                        message: INTEGER; param: LongInt) : LongInt;

VarCode is the variation code, as described above.

TheControl is a handle to the control that the operation will affect.

The message parameter identifies the desired operation. It has one of
the following values:

  CONST drawCntl = ¯;   {draw the control (or control part)}
    testCntl     = 1;   {test where mouse button was pressed}
    calcCrgns    = 2;   {calculate control's region (or indicator's)}
    initCntl     = 3;   {do any additional control initialization}
    dispCntl     = 4;   {take any additional disposal actions}
    posCntl      = 5;   {reposition control's indicator and update it}
    thumbCntl    = 6;   {calculate parameters for dragging indicator}
    dragCntl     = 7;   {drag control (or its indicator)}
    autoTrack    = 8;   {execute control's action procedure}

    As described below in the discussions of the routines that perform
these operations, the value passed for param, the last parameter of the
control definition function, depends on the operation. Where it's not 
mentioned below, this parameter is ignored. Similarly, the control
definition function is expected to return a function result only where
indicated; in other cases, the function should return ¯.

(note)
    "Routine" here does not necessarily mean a procedure or
     function. While it's a good idea to set these up as 
     subprograms inside the control definition function,
     you're not required to do so.
\ UpdtControl
6
PROCEDURE UpdtControl (theWindow: WindowPtr; updateRgn: RgnHandle);

    UpdtControl is a faster version of the DrawControls procedure.
Instead of drawing all of the controls in theWindow, UpdtControl
draws only the controls that are in the specified update region.
UpdtControl is called in response to an update event, and is usually
bracketed by calls to the Window Manager procedures BeginUpdate and
EndUpdate. UpdateRgn should be set to the visRgn of theWindowÕs port
(for more details, see the BeginUpdate procedure in the Window Manager
chapter).

Note:  In general, controls are in a dialog box and are automatically
drawn by the DrawDialog procedure.
\ Draw1Control
6
PROCEDURE Draw1Control (theControl: ControlHandle);

    Draw1Control draws the specified control if itÕs visible within the
window.
\ InitMenus
7
PROCEDURE InitMenus;

    InitMenus initializes the Menu Manager. It allocates space for the
menu list (a relocatable block on the heap large enough for the maximum
size menu list), and draws the (empty) menu bar. Call InitMenus once
before all other Menu Manager routines. An application should never
have to call this procedure more than once; to start afresh with all
new menus, use ClearMenuBar.

(note)
    The Window Manager initialization procedure InitWindows
    has already drawn the empty menu bar; InitMenus redraws
    it.
\ NewMenu
7
FUNCTION NewMenu (menuID: INTEGER; MenuTitle: Str255) : MenuHandle;

    NewMenu allocates space for a new menu with the given menu ID and
title, and returns a handle to it. It sets up the menu to use the
standard menu definition procedure. The new menu (which is created
empty) is not installed in the menu list. To use this menu, you must
first call AppendMenu or AddResMenu to fill it with items, InsertMenu
to place it in the menu list, and DrawMenuBar to update the menu bar to
include the new title.

    Application menus should always have positive menu IDs. Negative
menu IDs are reserved for menus belonging to desk accessories. No menu
should ever have a menu ID of ¯.

    If you want to set up the title of the Apple menu from your program
instead of reading it in from a resource file, you can use the
predefined constant appleMark (equal to $14, the value of the apple
symbol). For example, you can declare the string variable

    VAR myTitle: STRING[1];

and do the following:

    myTitle := ' ';
    myTitle[1] := CHR(appleMark)

    To release the memory occupied by a menu that you created with
NewMenu, call DisposeMenu.
\ GetMenu
7
FUNCTION GetMenu (resourceID: INTEGER) : MenuHandle;

    GetMenu returns a menu handle for the menu having the given resource
ID. It calls the Resource Manager to read the menu from the resource
file into a menu record in memory. It stores the handle to the menu
definition procedure in the menu record, reading the procedure from the
resource file into memory if necessary. To use this menu, you must
call InsertMenu to place it in the menu list and DrawMenuBar to update
the menu bar to include the new title.

(warning)
    Only call GetMenu once for a particular menu. If you
    need the menu handle to a menu that's already in memory, 
    use the Resource Manager function GetResource.

    To release the memory occupied by a menu that you read from a
resource file with GetMenu, use the Resource Manager procedure
ReleaseResource.
\ DisposeMenu
7
PROCEDURE DisposeMenu (theMenu: MenuHandle);

    Call ëisposeMenu to release the memory occupied by a menu that you
allocated with NewMenu. (For menus read from a resource file with
GetMenu, use the Resource Manager procedure ReleaseResource instead.)
This is useful if you've created temporary menus that you no longer
need.

(warning)
    Make sure you remove the menu from the menu list (with
    DeleteMenu) before disposing of it. Also be careful not
    to use the menu handle after disposing of the menu.


\ AppendMenu
7
PROCEDURE AppendMenu (theMenu: MenuHandle; data: Str255);

    AppendMenu adds an item or items to the end of the given menu, which
must previously have been allocated by NewMenu or read from a resource
file by GetMenu. The data string consists of the text of the menu
item; it may be blank but should not be the null string. If it begins
with a hyphen (-), the item will be a dividing line across the width of
the menu. As described in the section "Creating a Menu in Your 
Program", the following meta-characters may be embedded in the data
string:

   Meta-character     Usage
   --------------     -----

    ; or Return       Separates multiple items
    ^                 Followed by an icon number, adds that icon to
                      the item
    !                 Followed by a character, marks the item with
                      that character
    <                 Followed by B, I, U, O, or S, sets the
                      character style of the item
    /                 Followed by a character, associates a keyboard
                      equivalent with the item
    (                 Disables the item

    Once items have been appended to a menu, they cannot be removed or
rearranged. AppendMenu works properly whether or not the menu is in
the menu list.
\ AddResMenu
7
PROCEDURE AddResMenu (theMenu: MenuHandle; theType: ResType);

    AddResMenu searches all open resource files for resources of type
theType and appends the names of all resources it finds to the given
menu. Each resource name appears in the menu as an enabled item,
without an icon or mark, and in the normal character style. The
standard Menu Manager calls can be used to get the name or change its
appearance, as described below under "Controlling Items' Appearance".

(note)
    So that you can have resources of the given type that
    won't appear in the menu, any resource names that begin 
    with a period (.) or a percent sign (%) aren't apppended 
    by AddResMenu.

    Use this procedure to fill a menu with the names of all available
fonts or desk accessories. For example, if you declare a variable as

    VAR fontMenu: MenuHandle;

you can set up a menu containing all font names as follows:

    fontMenu := NewMenu(5,'Fonts');
    AddResMenu(fontMenu,"FONT')
\ InsertResMenu
7
Procedure InsertResMenu (theMenu: MenuHandle; theType: ResType;
                        afterItem: INTEGER);

    InsertResMenu is the same as AddRes÷enu (above) except that it
inserts the resource names in the menu where specified by the afterItem
parameter:  if afterItem is ¯, the names are inserted before the first
menu item; if it's the item number of an item in the menu, they're
inserted after that item; if it's equal to or greater than the last
item number, they're appended to the menu.

(note)
    InsertResMenu inserts the names in the reverse of the
    order that AddResMenu appends them. For consistency
    between the applications in the appearance of menus, use
    AddResMenu instead of InsertResMenu if possible.
\ InsertMenu
7
PROCEDURE InsertMenu (theMenu: MenuHandle; before ID: INTEGER);

    InsertMenu inserts a menu into the menu list before the menu whose
menu ID equals beforeID. If beforeID is ¯ (or isn't the ID of any menu
in the menu list), the new menu is added after all others. If the menu
is already in the menu list or the menu list is already full, InsertMenu
does nothing. Be sure to call DrawMenuBar to update the menu bar.
\ DrawMenuBar
7
PROCEDURE DrawMenuBar;

    DrawMenuBar redraws the menu bar according to the menu list,
incorporating any changes since the last call to DrawMenuBar. Any
highlighted menu title remains highlighted when drawn by DrawMenuBar.
This procedure should always be called after a sequence of InsertMenu
or DeleteMenu calls, and after ClearMenuBar, SetMenuBar, or any other
routine that changes the menu list.
\ DeleteMenu
7
PROCEDURE DeleteMenu (menuID: INTEGER);

    DeleteMenu deletes a menu from the menu list. If there's no menu
with the given menu ID in the menu list, DeleteMenu has no effect. Be
sure to call DrawMenuBar to update the menu bar; the menu titles
following the deleted menu will move over to fill the vacancy.

(note)
    DeleteMenu simply removes the menu from the list of
    currently available menus; it doesn't release the memory 
    occupied by the menu data structure.
\ ClearMenuBar
7
PROCEDURE ClearMenuBar;


    Call ClearMenuBar to remove all menus from the menu list when you
want to start afresh with all new menus. Be sure to call DrawMenuBar to
update the menu bar.

(note)
    ClearMenuBar, like Delete Menu, doesn't release the memory 
    occupied by the menu data structures; it merely removes
    them from the menu list.

    You don't have to call ClearMenuBar at the beginning of your
program, because InitMenus clears the menu list for you.
\ GetNewMBar
7
FUNCTION GetNewMBar (menuBarID: INTEGER) : Handle;

    GetNewMBar creates a menu list as defined by the menu bar resource
having the given resource ID, and returns a handle to it. If the
resource isn't already in memory, GetNewMBar reads it into memory from 
the resource file. It calls GetMenu to get each of the individual
menus.

    To make the menu list created by  GetNew÷Bar the  current menu list,
call SetMenuBar. To release the memory occupied by the menu list, use
the Memory Manager procedure DisposHandle.

(warning)

    You don't have to know the indivudual menu IDs to use 
    GetNewMBar, but that doesn't mean you don't have to know
    them at all:  to do anything further with a particular
    menu, you have to know its ID or its handle (which you
    can get by passing the ID to GetMHandle, as described
    below under "Miscellaneous Routines").


\ GetMenuBar
7
FUNCTION GetMenuBar : Handle;

    GetMenuBar creates a copy of the current menu list and returns a
handle to the copy. You can then add or remove menus from the menu list
(with InsertMenu, DeleteMenu, or ClearMenuBar), and later restore the
saved menu list with SetMenuBar. To release the memory occupied by the
saved menu list, use the Memory Manager procedure DisposHandle.

(warning)
    GetMenuBar doesn't copy the menus themselves, only a list 
    containing their handles. Do not dispose of any menus
    that might be in a saved menu list.
\ SetMenuBar
7
PROCEDURE SetMenuBar (menuList: Handle);

    SetMenuBar copies the given menu list to the current menu list. You
can use this procedure to restore a menu list previously saved by
GetMenuBar, or pass it a handle returned by GetNewMBar. Be sure to
call DrawMenuBar to update the menu bar.
\ MenuSelect
7
FUNCTION MenuSelect (startPt: Point) : LONGINT;

    When there's a mouse-down event in the menu bar, the application
should call MenuSelect with startPt equal to the point (in global
coordinates) where the mousebutton was pressed.  MenuSelect keeps
control until the mouse button is released, tracking the mouse, pulling
down menus as needed, and highlighting enabled menu items under the
cursor. When the mouse button is released over an enabled item in an
application menu, MenuSelect returns a long integer whose high-order
word is the menu ID of the menu, and whose low-order word is the menu
item number for the item chosen (see Figure 3). It leaves the selected
menu title highlighted. After performing the chosen task, your
application should call HiliteMenu(¯) to remove the highlighting from
the menu title.

    If no choice is made, MenuSelect returns ¯ in the high-order word of
the long integer, and the low-order word is undefined. This includes
the case where the mouse button is released over a disabled menu item
(such as Cut, Copy, Clear, or one of the dividing lines in Figure 3),
over any menu title, or outside the menu.

    If the mouse button is released over an enabled item in a menu
belonging to a desk accessory, MenuSelect passes the menu ID and item
number to the Desk Manager procedure SystemMenu for processing, and
returns ¯ to your application in the high-order word of the result.
\ MenuKey
7
FUNCTION MenuKey (ch: CHAR) : LONGINT;

    MenuKey maps the given character to the associated menu and item for
that character. When you get a key-down event with the Command key
held down--or an auto-key event, if the command being invoked is
repeatable--call MenuKey with the character that was typed. MenuKey
highlights the appropriate menu title, and returns a long integer
containing the menu ID in its high-order word and the menu item number
in its low-order word, just as MenuSelect does (see Figure 3 above).
After performing the chosen task, your application should call
HiliteMenu(¯) to remove the highlighting from the menu title.

    If the given character isn't associated with any enabled menu item 
currently in the menu list, MenuKey returns ¯ in the high-order word of
the long integer, and the low-order word is undefined.

    If the given character involes a menu item in a menu belonging to a
desk accessory, MenuKey (like MenuSelect) passes the menu ID and item
number to the Desk Manager procedure SystemMenu for processing, and
returns ¯ to your application in the high-order word of the result.

(note)
    There should never be more than one item in the menu list
    with the same keyboard equivalent, but if there is,
    MenuKey returns the first such item it encounters,
    scanning the menus from right to left and their items
    from top to bottom.
\ HiliteMenu
7
PROCEDURE HiliteMenu (menuID: INTEGER);

    Hilite Menu highlights the title of the given menu, or does nothing
if the title is already highlighted. Since only one menu title can be
highlighted at a time, it unhighlights any previously highlighted menu
title. If MenuID is ¯ (or isn't the ID of any menu in the menu list),
HiliteMenu simply unhighlights whichever menu title is highlighted (if
any).

    After MenuSelect or MenuKey, your application should perform the
chosen task and then call HiliteMenu(¯) to unhighlight the chosen menu
title.
\ SetItem
7
PROCEDURE SetItem (theMenu: MenuHandle; item: INTEGER; itemString:
    Str255);

    SetItem changes the text of the given menu item to itemString. It
doesn't recognize the meta-characters used in AppendMenu; if you
include them in itemString, they will appear in the text of the menu
item. The attributes already in effect for this item--its character
style, icon, and so on--remain in effect. ItemString may be blank but
should not be the null string.

(note)
    It's good practice to store the text of itemString in a 
    resource file instead of passing it directly.

    Use SetItem to flip between two alternative menu items--for example,
to change "Show Clipboard" top "Hide Clipboard" when the Clipboard is
already showing.

(note)
    To avoid confusing the user, don't capriciously change 
    the text of menu items.
\ GetItem
7
PROCEDURE GetItem (theMenu: MenuHandle; item: INTEGER; VAR itemString:
    Str255);

    GetItem returns the text of the given menu item in itemString. It
doesn't place any meta-characters in the string. This procedure is 
useful for getting the name of a menu item that was installed with
AddResMenu or InsertResMenu.
\ DisableItem
7
PROCEDURE DisableItem (theMenu: MenuHandle; item: INTEGER);

    Given a menu item number in the item parameter, DisableItem disables
that menu item; given ¯ in the item parameter, it disables the entire
menu.

    Disabled menu items appear dimmed and are not highlighted when the
cursor moves over them. MenuSelect and MenuKey return ¯ in the high-
order word of their result if the user attempts to invoke a disabled
item. Use DisableItem to disable all menu choices that aren't
appropriate at a given time (such as a Cut command when there's no text
selection).

    All menu items are initially enabled unless you specify otherwise
(such as by using the "(" meta-character in a call to AppendMenu).

    Every menu item in a disabled menu is dimmed. The menu title is
also dimmed, but you must call DrawMenuBar to update the menu bar to
show the dimmed title.
\ EnableItem
7
PROCEDURE EnableItem (theMenu:  MenuHandle; item: INTEGER);

    Given a menu item number in the item parameter, EnableItem enables
the item; given 0 in the item parameter, it enables the entire menu.
(The item or menu may have been disabled with the DisableItem procedure,
or the item may have been disabled with the "(" meta-character in the
AppendMenu string.)  The item or menu title will no longer appear
dimmed and can be chosen like any other enabled item or menu.
\ CheckItem
7
PROCEDURE CheckItem (theMenu:  MenuHandle; item:  INTEGER; checked:
            BOOLEAN);

    CheckItem places or removes a check mark at the left of the given
menu item. After you call CheckItem with checked=TRUE, a check mark
will appear each subsequent time the menu is pulled down. Calling
CheckItem with checked=FALSE removes the check mark from the menu item
(or, if it's marked with a different character, removes that mark).

    Menu items are initially unmarked unless you specify otherwise (such
as with the "!" meta-character in a call to AppendMenu).
\ SetItemMark
7
PROCEDURE SetItemMark (theMenu: MenuHandle; item: INTEGER; markChar:
             CHAR);

    SetItemMark marks the given menu item in a more general manner than
CheckItem. It allows you to place any character in the system font,
not just the check mark, to the left of the item. You can specify some
useful values for the markChar parameter with the following predefined
constants:

       CONST noMark      = 0;      {NUL character, to remove a mark}
             commandMark = $11;    {Command key symbol}
             checkMark   = $12;    {check mark}
             diamondMark = $13;    {diamond symbol}
             appleMark   = $14;    {apple symbol}
\ GetItemMark
7
PROCEDURE GetItemMark (theMenu: MenuHandle; item: INTEGER; VAR
            markChar: CHAR);

    GetItemMark returns in markChar whatever character the given menu
item is marked with, or the NUL character (ASCII code 0) if no mark is
present.
\ SetItemIcon
7
PROCEDURE SetItemIcon (theMenu: MenuHandle; item: INTEGER; icon: Byte);

    SetItemIcon associates the given menu item with an icon. It sets
the item's icon number to the given value (an integer from 1 to 255).
The Menu Manager adds 256 to the icon number to get the icon's resource
ID, which it passes to the Resource Manager to get the corresponding
icon.

(warning)
       If you deal directly with the Resource Manager to read or
       store menu icons, be sure to adjust your icon numbers
       accordingly.

Menu items initially have no icons unless you specify otherwise (such
as with the "^" meta-character in a call to AppendMenu).
\ GetItemIcon
7
PROCEDURE GetItemIcon (theMenu: MenuHandle; item: INTEGER; VAR icon:
                         Byte);

    GetItemIcon returns the icon number associated with the given menu
item, as an integer from 1 to 255, or 0 if the item has not been
associated with an icon. The icon number is 256 less than the icon's 
resource ID.
\ SetItemStyle
7
PROCEDURE SetItemStyle (theMenu: MenuHandle; item: INTEGER; chStyle:
                        Style);

    SetItemStyle changes the character style of the given menu item to
chStyle. For example:

    SetItemStyle(thisMenu,1,[bold,italic])     {bold and italic}

    Menu items are initially in the normal character style unless you
specify otherwise (such as with the "<" meta-character in a call to
AppendMenu).
\ GetItemStyle
7
PROCEDURE GetItemStyle (theMenu: MenuHandle; item: INTEGER; VAR
                        chStyle: Style);

    GetItemStyle returns the character style of the given menu item in
chStyle.
\ CalcMenuSize
7
PROCEDURE CalcMenuSize (theMenu: MenuHandle);

    You can use CalcMenuSize to recalculate the horizontal and vertical
dimensions of a menu whose contents have been changed (and store them
in the appropriate fields of the menu record). CalcMenuSize is called
internally by the Menu Manager after every AppendMenu, SetItem,
SetItemIcon, and SetItemStyle call.
\ GetMHandle
7
FUNCTION GetMHandle (menuID: INTEGER) : MenuHandle;

    Given the menu ID of a menu currently installed in the menu list,
GetMHandle returns a handle to that menu; given any other menu ID, it
returns NIL.
\ FlashMenuBar
7
PROCEDURE FlashMenuBar (menuID: INTEGER);

    If menuID is 0 (or isn't the ID of any menu in the menu list),
FlashMenuBar inverts the entire menu bar; otherwise, it inverts the
title of the given menu.
\ SetMenuFlash
7
PROCEDURE SetMenuFlash (count: INTEGER);

    When the mouse button is released over an enabled menu item, the
item blinks briefly to confirm the choice. Normally your application
shouldn't be concerned with this blinking; the user sets it with the
Control Panel desk accessory. If you're writing a desk accessory like
the Control Panel, though, SetMenuFlash allows you to control the
duration of this blinking. Count is the number of times menu items
will blink; it's initially 3 if the user hasn't changed it. A count of
0 disables blinking. Values greater than 3 can be annoyingly slow.

(warning)
    Don't call SetMenuFlash from your main program.     

(note)
    Items in both standard and nonstandard menus blink when
    chosen. The appearance of the blinking for a nonstandard
    menu depends on the menu definition procedure, as
    described below.
\ InsMenuItem
7
PROCEDURE InsMenuItem (theMenu: MenuHandle; itemString: Str255; afterItem: INTEGER);

    InsMenuItem inserts an item or items into the given menu where
specified by the afterItem parameter. If afterItem is 0, the items
are inserted before the first menu item; if itÕs the item number of an
item in the menu, theyÕre inserted after that item; if itÕs equal to or
greater than the last item number, theyÕre appended to the menu.

Warning:  Only the items contained in itemString are sorted.

    The contents of itemString are parsed as in the AppendMenu
procedure. Multiple items are inserted in the reverse of their order in
itemString.
\ DelMenuItem
7
PROCEDURE DelMenuItem (theMenu: MenuHandle; item: INTEGER);

    DelMenuItem deletes the specified item from the given menu.

Note:  DelMenuItem is intended for maintaining dynamic menus (such as
       a list of open windows). It should not be used for disabling
       items; you should use DisableItem instead.
\ TEInit
8
PROCEDURE TEInit;

    TEInit initializes TextEdit by allocating a handle for the TextEdit
scrap. The scrap is initially empty. Calll this procedure once and
only once at the beginning of your program.

(note)
      You should call TEInit even if your application doesn't
      use TextEdit, so that desk accessories and dialog and
      alert boxes will work correctly.
\ TENew
8
FUNCTION TENew (destRect, viewRect: Rect) : TEHandle;

    TENew allocates a handle for the text, creates and initializes an
edit record, and returns a handle to the new edit record. DestRect and
viewRect are the destination and view rectangles, respectively. Both
rectangles are specified in the current grafPort's coordinates. The
destination rectangle must always be at least as wide as the first
character drawn (about 20 pixels is usually a good width). The view
rectangle must not be empty (for example, don't make its right edge
less than its left edge if you don't want any text visible--specify a 
rectangle off the screen instead).

    Call TENew once for every edit record you want allocated. The edit
record incorporates the drawing environment of the grafPort, and is
initialized for left-justified, single-spaced text with an insertion
point at character position 0.

(note)
      The caret won't appear until you call TEActivate.
\ TEDispose
8
PROCEDURE TEDispose (hTE: TEHandle);

    TEDispose releases the memory allocated for the edit record and text
specified by hTE. Call this procedure when you're completely through
with an edit record.
\ TESetText
8
PROCEDURE TESetText (text: Ptr; length: LONGINT; hTE: TEHandle);

    TESetText incorporates a copy of the specified text into the edit
record specified by hTE. The text parameter points to the text, and
the length paramenter indicates the number of characters in the text.
The selection range is set to an insertion point at the end of the
text. TESetText doesn't affect the text drawn in the destination
rectangle, so call TEUpdate afterward if necessary. TESetText doesn't 
dispose of any text currently in the edit record.
\ TEGetText
8
FUNCTION TEGetText (hTE: TEHandle) : CharsHandle;

    TEGetText returns a handle to the text of the specified edit record.
The result is the same as the handle in the hText field of the edit
record, but has the CharsHandle data type, which is defined as:

       TYPE CharsHandle = ^CharsPtr;
            CharsPtr    = ^Chars;
        Chars       =PACKED ARRAY{0..3200] OF CHAR;

    You can get the length of the text from the teLength field of the
edit record.
\ TEIdle
8
PROCEDURE TEIdle (hTE: TEHandle);

    Call TEIdle repeatedly to make a blinking caret appear at the
insertion point (if any) in the text specified by hTE. (The caret
appears only when the window containing that text is active, of course.)
TextEdit observes a minimum blink interval:  No mater how often  you
call TEIdle, the time between blinks will never be less than the
minimum interval.

(note)
      You actually need to call TEIdle only when the window
      containing the text is active.
\ TEClick
8
PROCEDURE TEClick (pt: Point; extend: BOOLEAN; hTE: TEHandle);

    TEClick controls the placement and highlighting of the selection
range as determined by mouse events. Call TEClick whenever a mouse-down
event occurs in the view rectangle of the edit record specified by hTE,
and the window associated with that edit record is active. TEClick
keeps control until the mouse button is released. Pt is the mouse
location (in local coordinates) at the time the button was pressed,
obtainable from the event record.

(note)
      Use the QuickDraw procedure GlobalToLocal to convert the
      global coordinates of the mouse location given in the
      event record to the local coordinate system for pt.

    Pass TRUE for the extend parameter if the Event Manager indicates
that the Shift key was held down at the time of the click (to extend the
selection).

    TEClick unhighlights the old selection range unless the selection
range is being extended. If the mouse moves, meaning that a drag is
occurring, TEClick expands or shortens the selection range accordingly.
In the case of a double-click, the word under the cursor becomes the
selection range; dragging expands or shortens the selection a word at a
time.
\ TESetSelect
8
PROCEDURE TESetSelect (selStart,selEnd: LONGINT; hTE: TEHandle);

    TESetSelect sets the selection range to the text between selStart
and selEnd in the text specified by hTE. The old selection range is
unhighlighted, and the new one is highlighted. If selStart equals
selEnd, the selection range is an insertion point, and a caret is
displayed

    SelEnd and selStart can range from 0 to 32767. If selEnd is
anywhere beyond the last character of the text, the position just past
the last character is used.
\ TEActivate
8
PROCEDURE TEActivate (hTE: TEHandle);

    TEActivate highlights the selection range in the view rectangle of
the edit record specified by hTE. If the selection range is an
insertion point, it displays a caret there. This procedure should be
called every time the Toolbox Event Manager function GetNextEvent
reports that the window containing the edit record has become active.
\ TEDeactivate
8
PROCEDURE TEDeactivate (hTE: TEHandle);

    TEDeactivate unhighlights the selection range in the view rectangle
of the edit record specified by hTE. If the selection range is an
insertion point, it removes the caret. This procedure should be called
every time the Toolbox Event Manager function GetNextEvent reports that
the window containing the edit record has become inactive.
\ TEKey
8
PROCEDURE TEKey (key: CHAR; hTE: TEHandle);

    TEKey replaces the selection range in the text specified by hTE with
the character given by the key parameter, and leaves an insertion point
just past the inserted character. If the selection range is an
insertion point, TEKey just inserts the character there. If the key
parameter contains a Backspace character, the selection range or the
character immediately to the left of the insertion point is deleted.
TEKey redraws the text as necessary. Call TEKey every time the Toolbox
Event Manager function GetNextEvent reports a keyboard event that your
application decides should be handled by TextEdit.

(note)
      TEKey inserts every character passed in the key
      parameter, so it's up to your application to filter out
      all characters that aren't actual text (such as keys
      typed in conjuction with the Command key).
\ TECut
8
PROCEDURE TECut (hTE: TEHandle);

    TECut removes the selection range from the text specified by hTE and
places it in the TextEdit scrap. The text is redrawn as necessary.
Anything previously in the scrap is lost. (See Figure 6.)  If the
selection range is an insertion point, the scrap is emptied.
\ TECopy
8
PROCEDURE TECopy (hTE: TEHandle);

    TECopy copies the selection range from the text specified by hTE
into the TextEdit scrap. Anything previously in the scrap is deleted.
The selection range is not deleted. If the selection range is an
insertion point, the scrap is emptied.
\ TEPaste
8
PROCEDURE TEPaste (hTE: TEHandle);

    TEPaste replaces the selection range in the text specified by hTE
with the contents of the TextEdit scrap, and leaves an insertion point
just past the inserted text. (See Figure 7.)  The text is redrawn as
necessary. If the scrap is empty, the selection range is deleted. If
the selection range is an insertion point, TEPaste just inserts the
scrap there.
\ TEDelete
8
PROCEDURE TEDelete (hTE: TEHandle);

    TEDelete removes the selection range from the text specified by hTE,
and redraws the text as necessary. TEDelete is the same as TECut
(above) except that it doesn't transfer the selection range to the
scrap. If the selection range is an insertion point, nothing happens.
\ TEInsert
8
PROCEDURE TEInsert (text: Ptr; length: LONGINT; hTE: TEHandle);

    TEInsert takes the specified text and inserts it just before the
selection range into the text indicated by hTE, redrawing the text as
necessary. The text parameter points to the text to be inserted, and
the length parameter indicates the number of characters to be inserted.
TEInsert doesn't affect either the current  selection range or the
scrap.
\ TESetJust
8
PROCEDURE TESetJust (just: INTEGER, hTE: TEHandle);

    TESetJust sets the justification of the text specified by hTE to
just. (See"Justification" under "Edit Records".)  TextEdit provides
three predefined constants for setting justification:

        CONST: teJustLeft   = 0;
               teJustCenter = 1;
               teJustRight  = -1;

    By default, text is left-justified. If you change the
justification, call TEUpdate after TESetJust, to redraw the text with
the new justification.
\ TEUpdate
8
PROCEDURE TEUpdate (rUpdate: Rect; hTE: TEHandle);

    TEUpdate draws the text specified by hTE within the rectangle
specified by rUpdate. The rUpdate rectangle must be given in the
coordinates of the current grafPort. Call TEUpdate every time the
Tolbox Event Manager function GetNextEvent reports an update event for a
text editing window--after you call the Window Manager procedure
BeginUpdate, and before you call EndUpdate.

Normally you'll do the following when an update event occurs:

       BeginUpdate(myWindow);
       EraseRect(myWindow^.portRect);
       TEUpdate(myWindow^I.protRect,hTE);
       EndUpdate(myWindow)

    If you don't include the EraseRect call, the caret may sometimes
remain visible when the window is deactivated.
\ TextBox
8
PROCEDURE TextBox (text: Ptr; length: LONGINT; box: Rect; just:
            INTEGER);

    TextBox draws the specified text in the rectangle indicated by the
box parameter with justification just. (See "justification" under "Edit
Records".)  The text parameter points to the text, and the length
parameter indicates the number of characters to draw. The rectangle is
specified in local coordinates, that must be at least as wide as the
first character drawn (about 20 pixels is usually a good width).
TextBox does not create an edit record, nor can the text that it draws
be edited; it's used solely for drawing text. For example:

    str := 'String in a box';
    SetRect(r,100,100,200,200);
    TextBox(POINTER(ORD(@str)+1),LENGTH(str),r,teJustCenter);
    FrameRect(r)

    Because Pascal strings start with a length byte, you must advance
the pointer one position past the beginning of the string to point to
the start of the text.
\ TEScroll
8
PROCEDURE TEScroll (dh,dv: INTEGER; hTE: TEHandle);

    TEScroll scrolls the text within the view rectangle of the specified
edit record by the number of pixels specified in the dh and dv
parameters. The edit record is specified by the hTE parameter.
Positive dh and dv values move the text right and down, respectively,
and negative values move the text left and up. For example,

     TEScroll(0,-hTE^^.lineHeight,hTE)

scrolls the text up one line. Remember that you scroll text up when
the user clicks in the scroll arrow pointing down. The destination
rectangle is offset by the amount you scroll.

(note)
      To implement automatic scrolling, you store the address
      of a routine in the clikLoop field of the edit record, as
      described above under "The TERec Data Type".
\ TEFromScrap
8
FUNCTION TEFromScrap : OSErr;  [Not in ROM]

    TEFromScrap copies the desk scrap to the TextEdit scrap.
\ TEToScrap
8
FUNCTION TEToScrap : OSErr;  [Not in ROM]

    TEToScrap copies the TextEdit scrap to the desk scrap.

(warning)
         You must call the Scrap Manager function ZeroScrap to
     initialize the desk scrap or clear its previous contents
     before calling TEToScrap.
\ TEScrapHandle
8
FUNCTION TEScarapHandle : Handle;  [Not in ROM]

    TEScrapHandle returns a handle to the TExtEdit scrap.
\ TEGetScrapLen
8
FUNCTION TEGetScrapLen : LONGINT; [Not in ROM]

    TEGetScrapLen returns the size of the TextEdit scrap in bytes.
\ TESetScrapLen
8
PROCEDURE TESetScrapLen (length: LONGINT); [Not in ROM]

    TESetScrapLen sets the size of the TextEdit scrap to the given
number of bytes.
\ TECalText
8
PROCEDURE TECalText (hTE: TEHandle);

    TECalText recalculates the beginnings of all lines of text in the
edit record specified by hTE, updating elements of the lineStarts array.
Call  TECalText if you've changed the destination rectangle, the hText
field, or any other field that affects the number of characters per line.

(note)
      There are two ways to specify text to be edited. The
      easiest method is to use TESetText, which takes an
      existing edit record, creates a copy of the specified
      text, and stores a handle to the copy in the edit record.
      You can instead directly change the hText field of the
      edit record, and then call TECalText to recalculate the
      lineStarts aray to match the new text. If you have a
      lot of text, you can use the latter method to save space.
\ TESelView
8
PROCEDURE TESelView (hTE: TEHandle);

    If automatic scrolling has been enabled (by a call to TEAutoView,
described below), TESelView makes sure that the selection range is
visible, scrolling it into the view rectangle if necessary.
If automatic scrolling is disabled, TESelView does nothing.

Note:  The top left of the insertion is scrolled into view; if text
is being displayed in a rectangle thatÕs not tall enough, automatic
scrolling could cause the text to jump up and down at times.
\TEPinScroll
8
PROCEDURE TEPinScroll (dh,dv: INTEGER; hTE: TEHandle);

    TEPinScroll is similar to TEScroll except that it stops scrolling
when the last line scrolls into the view rectangle.
\TEAutoView
8
PROCEDURE TEAutoView (auto: BOOLEAN; hTE: TEHandle);

    TEAutoView enables and disables automatic scrolling of text in the
edit record specified by hTe. If the auto parameter is FALSE,
automatic scrolling is disabled and calling TESelView has no effect.
\ InitDialogs
9
PROCEDURE InitDialogs (restartProc: ProcPtr);

    Call InitDialogs once before all other Dialog Manager routines, to
initialize the Dialog Manager.

  -It sets a pointer to a fail-safe procedure as specified by
   restartProc; this pointer will be accessed when a system error
   (such as running out of memory) occurs. RestartProc should point
   to a procedure that will restart the application after a system
   error. If no such procedure is desired, pass NIL as the parameter.

  -It installs the standard sound procedure.

  -It passes empty strings to ParamText.
\ ErrorSound
9
PROCEDURE ErrorSound (soundProc: ProcPtr);

    ErrorSound sets the sound procedure for dialogs and alerts to the
procedure pointed to by soundProc; if you don't call ErrorSound, the
Dialog Manager uses the standard sound procedure. (For details, see
the "Alerts" section abouve.)  If you pass NIL for soundProc, there will
be no sound (or menu bar blinking) at all.
\ SetDAFont
9
PROCEDURE SetDAFont (fontNum: INTEGER);  [Pascal only]

    For subsequently created dialogs and alerts, SetDAFont sets the font
of the dialog or alert window's grafPort to the font having the
specified font number. If you don't call this procedure, the system
font is used. SetDAFont affects statText and editText items but not
titles of controls, which are always in the system font.
\ NewDialog
9
FUNCTION NewDialog (dStorage: Ptr; boundsRect: Rect; title: Str255;
            visible: BOOLEAN; procID: INTEGER; behind: WindowPtr;
        goAwayFlag: BOOLEAN; refCon: LongInt; items: Handle) :
        DialogPtr;

    NewDialog creates a dialog as specified by its parameters and
returns a pointer to the new dialog. The first eight parameters
(dStorage through refCon) are pased to the Window Manager function
NewWindow, which creates the dialog window; the meanings of these
parameters are summarized below. The items parameter is a handle to the
dialog's item list. You can get the items handle by calling the
Resource Mangager to read the item list from the resource file into
memory.

(note)
      Advanced programmers can create their own item lists in
      memory rather than have them read from a resource file.
      The exact format is given later under "Formats of
      Resources for Dialogs and Alerts".

    DStorage is analogous to the wStorage parameter of NewWindow; it's a
pointer to the storage to use for the dialog record. If you pass NIL
for dStorage, the dialog record will be allocated on the heap (which,
in the case of modeless dialogs, may cause the heap to become
fragmented).

    BoundsRect, a rectangle given in global coordinates, determines the
dialog window's size and location. It becomes the portRect of the
window's grafPort. Remember that the top coordinate of this rectangle
should be at least 25 points below the top of the screen for a modal
dialog, to allow for the menu bar and the border around the portRect,
and at least 40 points below the top of the screen for a modeless
dialog, to allow for the menu bar and the window's title bar.

    Title is the title of a modeless dialog box; pass the empty string
for modal dialogs.

    If the visible parameter is TRUE, the dialog window is drawn on the
screen. If it's FALSE, the window is initially invisible and may later
be shown with a call to the Window Manager procedure ShowWindow.

(note)
      NewDialog generates an update event for the entire window
      contents, so the items aren't drawn immediately, with the
      exception of controls. The Dialog Manager calls the
      Control Manager to draw controls, and the Control Manager
      draws them immediately rather than via the standard
      update mechanism. Because of this, the Dialog Manager
      calls the Window Manager procedure ValidRect for the
      enclosing rectangle of each control, so the controls
      won't be drawn twice. If you find that the other items
      aren't being drawn soon enough after the controls, try 
      making the window invisible initially and then calling
      ShowWindow to show it.

    ProcID is the window definition ID, which leads to the window
definition function for this type of window. The window definition IDs
for the standard types of dialog window are dBoxProc for the modal type
and documentProc for the modeless type.

    The behind parameter specifies the window behind which the dialog
window is to be placed on the desktop. Pass POINTER(-1) to bring up
the dialog window in front of all other windows.

    GoAwayFlag applies to modeles dialog boxes; if it's TRUE, the dialog
window has a close box in its title bar when the window is active.

    RefCon is the dialog window's reference value, which the application
may store into and access for any purpose.

    NewDialog sets the font of the dialog window's grafPort to the
system font or, if you previously called SetDAFont, to the specified
font. It also sets the window class in the window record to dialogKind.
\ GetNewDialog
9
FUNCTION GetNewDialog (dialogID: INTEGER; dStorage: Ptr; behind:
            WindowPtr) : DialogPtr;

    Like NewDialog (above), GetNewDialog creates a dialog as specified
by its parameters and returns a pointer to the new dialog. Instead of
having the parameters boundsRect, title, visible, procID, goAwayFlag,
and refCon, GetNewDialog has a single dialogID parameter, where
dialogID is the resource ID of a dialog template that supplies the same
information as those parameters. The dialog template also contains the
resource ID of the dialog's item list. After calling the Resource
Manager to read the item list into memory (if it's not already in
memory), GetNewDialog makes a copy of the item list and uses that copy;
thus you may have multiple independent dialogs whose items have the
same types, locations, and initial contents. The dStorage and behind
parameters of GetNewDialog have the same meaning as in NewDialog.
\ CloseDialog
9
PROCEDURE CloseDialog (theDialog: DialogPtr);

    CloseDialog removes theDialog's window from the screen and deletes
it from the window list, just as when the Window Manager procedure
CloseWindow is called. It releases the memory occupied by the
following:

  -The data structures associated with the dialog window (such as the
   window's structure, content, and update regions).

  -All the items in the dialog (except for pictures and icons, which
   might be shared resources), and any data structures associated
   with them. For example, it would dispose of the region occupied
   by the thumb of a scroll bar, or a similar region for some other
   control in the dialog.

    CloseDialog does not dispose of the dialog record or the item list.
Figure 6 illustrates the effect of CloseDialog (and DisposDialog,
described below).

    Call CloseDialog when you're done with a dialog if you supplied
NewDialog or GetNewDialog with a pointer to the dialog storage (in the
dStorage parameter) when you created the dialog.

(note)
      Even if you didn't supply a pointer to the dialog
      storage, you may want to call CloseDialog if you created
      the dialog with NewDialog. You would call CloseDialog if
      you wanted to keep the item list around (since, unlike
      GetNewDialog, NewDialog does not use a copy of the item
      list).
\ DisposDialog
9
PROCEDURE DisposDialog (theDialog: DialogPtr);

    DisposDialog calls CloseDialog (above) and then releases the memory
occupied by the dialog's item list and dialog record. Call
DisposDialog when you're done with a dialog if you let the dialog
record be allocated on the heap when you created the dialog (by passing
NIL as the dStorage parameter to NewDialog or GetNewDialog).
\ CouldDialog
9
PROCEDURE CouldDialog (dialogID:  INTEGER);

    CouldDialog ensures that the dialog template having the given
resource ID is in memory and makes it unable to be purged. It does the
same for the dialog window's definition function, the dialog's item list
resource, and any item defined as resources. This is useful if the
dialog box may come up when the resource file isn't accessible, such as
during a disk copy.
\ FreeDialog
9
PROCEDURE FreeDialog (dialogID: INTEGER);

    Given the resource ID of a dialog template previously specified in a
call to CouldDialog (above), FreeDialog undoes the effect of
CouldDialog. It should be called when there's no longer a need to keep
the resources in memory.
\ ModalDialog
9
PROCEDURE ModalDialog (filterProc: ProcPtr; VAR itemHit: INTEGER);

    Call ModalDialog after creating a modal dialog and bringing up its
window in the frontmost plane. ModalDialog repeatedly gets and handles
events in the dialog's window; after handling an event involving an
enabled dialog item, it returns with the item number in itemHit.
Normally you'll then do whatever is appropriate as a response to an 
event in that item.

    ModalDialog gets each event by calling the Toolbox Event Manager
function GetNextEvent. If the event is a mouse-down event outside the
content region of the dialog window, ModalDialog emits sound number 1
(which should be a single beep) and gets the next event; otherwise, it
filters and handles the event as described below.

(note)
      Once before getting each event, ModalDialog calls
      SystemTask, a Desk Manager procedure that needs to be
      called regularly if the application is to support the use
      of desk accessories.

    The filterProc parameter determines how events are filtered. If it's
 NIL, the standard filterProc function is executed; this causes
 ModalDialog to return 1 in itemHit if the Return key or Enter key is
 pressed. If filterProc isn't NIL, ModalDialog filters events by
 executing the function it points to. Your filterProc function should
 have three parameters and return a Boolean value. For example, this is
 how it would be declared if it were named MyFilter:

      FUNCTION MyFilter (theDialog: DialogPtr; VAR theEvent:
                         EventRecord; VAR itemHit: INTEGER ) : BOOLEAN;

    A function result of FALSE tells ModalDialog to go ahead and handle
the event, which either can be sent through unchanged or can be changed
to simulate a different event. A function result of TRUE tells
ModalDialog to return imediately rather than handle the event; in this
case, the filterProc function sets itemHit to the item number that
ModalDialog should return.

(note)
      ModalDialog calls GetNextEvent with a mask that excludes
      disk-inserted events. To receive disk-inserted events,
      your filterProc function can call GetNextEvent (or
      EventAvail) with a mask that accepts only that type of event.

    ModalDialog handles the evnets for which the filterProc function
returns FALSE as follows:

  -In response to an activate or update event for the dialog window,
   ModalDialog activates or updates the window.

  -If the mouse button is pressed in an editText item, ModalDialog
   responds to the mouse activity as appropriate (displaying an
   insertion point or selecting text). If a key-down event occurs
   and there's an editText item, text entry and editing are handled
   in the standard way for such items (except that if the Command key
   is down, ModalDialog responds as though it isn't). In either
   case, ModalDialog returns if the editText item is enabled or does
   nothing if it's disabled. If a key-down event occurs when there's
   no editText item, ModalDialog does nothing.

  -If the mouse button is pressed in a control, ModalDialog calls the
   Control Manager function TrackControl. If the mouse button is
   released inside the control and the control is enabled,
   ModalDialog returns; otherwise, it does nothing.

  -If the mouse button is pressed in any other enabled item in the
   dialog box, ModalDialog returns. If the mouse button is pressed
   in any other disabled item or in no item, or if any other event
   occurs, ModalDialog does nothing.
\ IsDialogEvent
9
FUNCTION IsDialogEvent (theEvent: EventRecord) : BOOLEAN;

    If your application includes any modeless dialogs, call
IsDialogEvent after calling the Toolbox Event Manager function
GetNextEvent. Pass the current event in theEvent. IsDialogEvent
determines whether theEvent needs to be handled as part of a dialog. If
theEvent is an activate or update event for a dialog window, a
mouse-down event in the content region of an active dialog window, or
any other type of event when a dialog window is active, IsDialogEvent
returns TRUE; otherwise, it returns FALSE.

    When FALSE is returned, just handle the event yourself like any
other event that's not dialog-related. When TRUE is returned, you'll
generally end up passing the event to DialogSelect for it to handle (as
described below), but first you should do some additional checking:

   - DialogSelect doesn't handle keyboard equivalents for commands.
     Check whether the event is a key-down event with the Command key
     held down and, if so, carry out the command if it's one that
     applies when a dialog window is active. (If the command doesn't
     so apply, do nothing.)

  - In special cases, you may want to bypass DialogSelect or do some
    preprocessing before calling it. If so, check for those events
    and respond accordingly. You would need to do this, for example,
    if the dialog is to respond to disk-inserted events.

    For cases other than these, pass the event to DialogSelect for it to
handle.
\ DialogSelect
9
FUNCTION DialogSelect (theEvent: EventRecord; VAR theDialog: DialogPtr;
            VAR itemHit: INTEGER) : BOOLEAN;

    You'll normally call DialogSelect after IsDialogEvent, passing in
theEvent an event that needs to be handled as part of a modeless
dialog. DialogSelect handles the event as described below. If the
event involves an enabled dialog item, DialogSelect returns a function
result of TRUE with the dialog pointer in theDialog and the item number
in itemHit; otherwise, it returns FALSE with theeDialog and itemHit
undefined. Normally when DialogSelect returns TRUE, you'll do whatever
is appropriate as a response to the event, and when it returns FALSE
you'll do nothing.

    If the event is an activate or update event for a dialog window,
DialogSelect activates or updates the window ane returns FALSE.

    If the event is a mouse-down event in an editText item, DialogSelect
responds as appropriate (displaying an insertion point or selecting
text). If it's a key-down event and there's an editText item, text
entry and editing are handled in the standard way. In either case,
DialogSelect returns TRUE if the editText item is enabled or FALSE if
it's disabled. If a key-down event is passed when there's no editText
item, DialogSelect returns FALSE.

(note)
      For a key-down event, DialogSelect doesn't check to see
      whether the Command key is held down; to handle keyboard
      equivalents of commands, you have to check for them
      before calling DialogSelect. Similarly, to treat a typed
      character in a special way (such as ignore it, or make it
      have the same effect as another character or as clicking
      a button), you need to check for a key-down event with
      that character before calling DialogSelect.

    If the event is a mouse-down event in a control, DialogSelect calls
the Control Manager function TrackControl. If the mouse button is
released inside the control and the control is enabled, DialogSelect
returns TRUE; otherwise, it returns FALSE.

    If the event is a mouse-down event in any other enabled item,
DialogSelect returns TRUE. If it's  a mouse-down event in any other
disabled item or in no item, or if it's any other event, DialogSelect
returns FALSE.
\ DlgCut
9
PROCEDURE DlgCut (theDialog: DialogPtr);   [Pascal only]

    DlgCut checks whether theDialog has any editText items and, if so,
applies the textEdit procedure TECut to the currently selected editText
item. (If the dialog record's editField is 0 or greater, DlgCut passes
the contents of the textH field to TECut.)  You can call DlgCut to
handle the editing command Cut when a modeless dialog window is active.
\ DlgCopy
9
PROCEDURE DlgCopy (theDialog: DialogPtr);   [Pascal only]

    DlgCopy is the same as DlgCut (above) except that it calls TECopy,
for handling the Copy command.
\ DlgPaste
9
PROCEDURE DlgPaste (theDialog: DialogPtr);   [Pascal only]

    DlgPaste is the same as DlgCut (above) except that it calls TEPaste,
for handling the Paste command.
\ DlgDelete
9
PROCEDURE DlgDelete (theDialog: DialogPtr);   [Pascal only]

    DlgDelete is the same as DlgCut (above) except that it calls
TEDelete, for handling the Clear command.
\ DrawDialog
9
PROCEDURE DrawDialog (theDialog: DialogPtr);

    DrawDialog draws the contents of the given dialog box. Since
DialogSelect and ModallDialog handle dialog window updating, this
procedure is useful only in unusual situations. You would call it, for
example, to display a dialog box that doesn't require any response but
merely tells the user what's going on during a time-consuming process.
\ Alert
9
FUNCTION Alert (alertID: INTEGER; filterProc: ProcPtr) : INTEGER;

    This function invokes the alert defined by the alert template that
has the given resource ID. It calls the currnet sound procedure, if
any,l passing it the sound number specified in the alert template for
this stage of the alert. If no alert box is to be drawn at this stage,
Alert returns a function result of -1; otherwise, it creates and
displays the alert window for this alert and draws the alert box.

(note)
      It creates the alert window by calling NewDialog, and
      does the rest of its processing by calling ModalDialog.

    Alert repeatedly gets and handles events in the alert window until
an enabled item is clicked, at which time it returns the item number.
Normally you'll then do whatever is appropriate in response to a click
of that item.

    Alert gets each event by calling theToolbox Event Manager function
GetNextEvent. If the event is a mouse-down event outside the content
region of the alert window, Alert emits sound number 1 (which should be
a single beep) and gets the next event; otherwise, it filters and
handles the event as describe below.

    The filterProc parameter has the same meaning as in ModalDialog (see
above). If it's NIL, the standard filterProc function is executed,
which makes the Return key or the Enter key have the same effect as
clicking the default button. If you specify your own filterProc
function and want to retain this feature, you must include it in your
function. You can find out what the current default button is by
looking at the aDefItem field of the dialog record for the alert (via
the dialog pointer passed to the function).

    Alert handles the events for which the filterProc function returns
FALSE as follows:


  - If the mouse button is pressed in a control, Alert calls the
    Control Manager procedure TrackControl. If the mouse buton is
    released inside the control and the control is enabled, Alert
    returns; otherwise, it does nothing.

  - If the mouse button is pressed in any other enabled item, Alert
    simply returns. If it's pressed in any other disabled item or in 
    no item, or if any other event occurs, Alert does nothing.

    Before returning to the application with the item number, Alert
removes the alert box from the screen. (It disposes of the alert window
and its associated data structures, the item list, and the items.)

(note)
       The Alert function's removal of the alert box would not
       be the desired result if the user clicked a check box or
       radio button; however, normally alerts contain only
       static text, icons, pictures, and buttons that are
       supposed to make the alert box go away. If your alert
       contains other items besides these, consider whether it
       might be more appropriate as a dialog.
\ StopAlert
9
FUNCTION StopAlert (alertID: INTEGER; filterProc: ProcPtr) : INTEGER;

    StopAlert is the same as the Alert function (above) except that
before drawing the items of the alert in the alert box, it draws the
Stop icon in the top left corner of the box (within the rectangle
(10,20,42,52)). The Stop icon has the following resource ID:

       CONST stopIcon = 0;

    If the application's resource file doesn't include an icon with that
ID number, the Dialog Manager uses the standart Stop icon in the system
resource file (see Figure 7).
\ NoteAlert
9
FUNCTION NoteAlert (alertID: INTEGER; filterProcf: ProcPtr) : INTEGER;

    NoteAlert is like StopAlert except that it draws the Note icon,
which has the following resource ID:

       CONST noteIcon = 1;
\ CautionAlert
9
FUNCTION CautionAlert (alertID: INTEGER; filterProc: ProcPtr) :
           INTEGER;

    CautionAlert is like StopAlert except that it draws the Caution
icon, which has the following resource ID:

       CONST ctnIcon = 2;
\ CouldAlert
9
PROCEDURE CouldAlert (alertID: INTEGER);

    CouldAlert ensures that the alert template having the given resource
ID is in memory and makes it unable to be purged. It does the same for
the alert window's definition function, the alert's item list resource,
and any items defined as resources. This is useful if the alert may
occur when the resource file isn't accessible, such as during a disk
copy.
\ FreeAlert
9
PROCEDURE FreeAlert (alertID: INTEGER);

    Given the resource ID of an alert template previously specified in a
call to CouldAlert (above), FreeAlert undoes the effect of CouldAlert.
It should be called when there's no longer a need to keep the resources
in memory.
\ ParamText
9
PROCEDURE ParamText (param0,param1,param2,param3: Str255);

    ParamText provides a means of substituting text in statText items:
param0 through param3 will replace the special strings '^0' through
'^I3' in all statText items in all subsequent dialog or alert boxes.
Pass empty strings for parameters not used.

    For example, if the text is defined as 'Cannot open document ^0' and
docName is a string variable containg a document name that the user
typed, you can call ParamText(docName, '','','').

(warning)
         All strings that will need to be translated to foreign
        languages should be stored in resource files.



\ GetDItem
9
PROCEDURE GetDItem (theDialog: DialogPtr; itemNo: INTEGER; VAR type:
                    INTEGER; VAR item: Handle; VAR box: Rect);

    GetDItem returns in its VAR parameters the following information
about the item numbered itemNo in the given dialog's item list: in the
type parameter, the item type; in the item parameter, a handle to the
item (or, for item type userItem, the procedure pointer); and in the box
parameter, the display rectangle for the item.

    Suppose, for example, that you want to change the title of a control
in a dialog box. You can get the item handle with GetDItem, convert it
to type ControlHandle, and call the Control Manager procedure SetCTitle
to change the title. Similarly, to move the control or change its size,
you would call MoveControl or SizeControl.

(note)
      To access the text of a statText or editText item, pass
      the handle returned by GetDItem to GetIText or SetIText
      (see below).
\ SetDItem
9
PROCEDURE SetDItem (theDialog: DialogPtr; itemNo: INTEGER; type:
            INTEGER; item: Handle; box: rect);

    SetDItem sets the item numbered itemNo in the given dialog's item
list, as specified by the parameters (without drawing the item). The
type parameter is the item type; the item parameter is a handle to the
item (or, for item type userItem, the procedure pointer); and the box
parameter is the display rectangle for the item.

    Consider, for example, how to install an item of type userItem in a
dialog:  In the item list in the resource file, define an item in which
the type is set to userItem and the display rectangle to (0,0,0,0).
Specify that the dialog window be invisible (in either the dialog
template or the NewDialog call). After creating the dialog, convert
the item's procedure pointer to type Handle; then call SetDItem,
passing that handle and the display rectangle for the item. Finally,
call the Window Manager procedure ShowWindow to display the dialog
window.

(note)
      Do not use SetDItem to change the text of a statText or
      editText item or to change or move a control. See the
      description of GetDItem above for more information.
\ GetIText
9
PROCEDURE GetIText (item: Handle; VAR text: str255);

    Given a handle to a statText or editText item in a dialog box, as
returned by GetDItem, GetIText returns the text of the item in the text
parameter.
\ SetIText
9
PROCEDURE SetIText (item: Handle; text: Str255);

    Given a handle to a statText or editText item in a dialog box, as
returned by GetDItem, SetIText sets the text of the item to the
specified text and draws the item. For example, suppose the exact
content of a dialog's text item cannot be determined until the
application is running, but the display rectangle is defined in the
resource file:  Call GetDItem to get a handle to the item, and call
SetIText with the desired text.
\ SelIText
9
PROCEDURE SelIText (theDialog: DIalogPtr; itemNo: INTEGER;
           strtSel,endSel: INTEGER);

    Given a pointer to a dialog and the item number of an editText item
in the dialog box, SelIText does the following:

   - If the item contains text, SelIText sets the selection range to
     extend from character position strtSel up to but not including
     character position endSel. The selection range is inverted unless
     strtSel equals endSel, in which case a blinking vertical bar is
     displayed to indicate an insertion point at that position.

   - If the item doesn't contain text, SelIText simply displays the
     insertion point.

    For example, if the user makes an unacceptable entry in the editText
item, the application can put up an alert box reporting the problem and
then select the entire text of the item so it can be replaced by a new
entry. (Without this procedure, the user would have to select the item
before making the new entry.)

(note)
      You can select the entire text by specifying 0 for
      strtSel and a very large number for endSel. For details
      about selection range and character position, see the
      TextEdit manual.
\ GetAlrtStage
9
FUNCTION GetAlrtStage : INTEGER;   [Pascal only]

    GetAlrtStage returns the stage of the last occurrence of an alert,
as a number from 0 to 3.
9
PROCEDURE ResetAlrtStage;   [Pascal only]

    ResetAlrtStage resets the stage of the last occurrence of an alert
so that the next occurrenct of the same alert will be treatd as its
first stage. This is useful, for example, when you've used ParamText
to change the text of an alert such that from the user's point of view
it's a different alert.
\ HideDItem
9
PROCEDURE HideDItem (theDialog: DialogPtr; itemNo: INTEGER);

    HideDItem hides the item numbered itemNo in the given dialogÕs item
list by giving the item a display rectangle thatÕs off the screen.
(Specifically, if the left coordinate of the itemÕs display rectangle
is less than 8192, ShowDItem adds 16384 to both the left and right
coordinates the rectangle.)  If the item is already hidden (that is,
if the left coordinate is greater than 8192), HideDItem does nothing.

    HideDItem calls the EraseRect procedure on the itemÕs enclosing
rectangle and adds the rectangle that contained the item (not
necessarily the itemÕs display rectangle) to the update region.
If the specified item is an active editText item, the item is first
deactivated (by calling TEDeactivate).

Note:  If you have items that are close to each other, be aware that
       the Dialog Manager draws outside of the enclosing rectangle by 3
       pixels for editText items and by 4 pixels for a default button.

    An item thatÕs been hidden by HideDItem can be redisplayed by the
ShowDItem procedure.

Note:  To create a hidden item in a dialog item list, simply add
       16384 to the left and right coordinates of the display rectangle.
\ ShowDItem
9
PROCEDURE ShowDItem (theDialog: DialogPtr; itemNo: INTEGER);

    ShowDItem redisplays the item numbered itemNo, previously hidden by
HideDItem, by giving the item the display rectangle it had prior to
the HideDItem call. (Specifically, if the left coordinate of the
itemÕs display rectangle is greater than 8192, ShowDItem subtracts
16384 from both the left and right coordinates the rectangle.)
If the item is already visible (that is, if the left coordinate is
less than 8192), ShowDItem does nothing.

    ShowDItem adds the rectangle that contained the item (not
necessarily the itemÕs display rectangle) to the update region so
that it will be drawn. If the item becomes the only editText item,
ShowDItem activates it (by calling TEActivate).
\FindDItem
9
FUNCTION FindDItem (theDialog: DialogPtr; thePt: Point) : INTEGER;

    FindDItem returns the item number of the item containing the point
specified, in local coordinates, by thePt. If the point doesnÕt lie
within the itemÕs rectangle, FindDItem returns Đ1.  If there are
overlapping items, it returns the item number of the first item in
the list containing the point. FindDItem is useful for changing the
cursor when itÕs over a particular item.

Note:  FindDItem will return the item number of disabled items as well.
\UpdtDialog
9
PROCEDURE UpdtDialog (theDialog: DialogPtr; updateRgn: RgnHandle);

    UpdtDialog is a faster version of the DrawDialog procedure.
Instead of drawing the entire contents of the given dialog box,
UpdtDialog draws only the items that are in a specified update region.
UpdtDialog is called in response to an update event, and is usually
bracketed by calls to the Window Manager procedures BeginUpdate and
EndUpdate. UpdateRgn should be set to the visRgn of theWindowÕs port.
(For more details, see the BeginUpdate procedure in chapter 9 of
Volume I.)
\ OpenDeskAcc
10
FUNCTION OpenDeskAcc (theAcc: Str255) : INTEGER;

    OpenDeskAcc opens the desk accessory having the given name and
displays its window (if any) as the active window. The name is the
accessory's resource name, which you get from the Apple menu by calling
the Menu Manager procedure GetItem. OpenDeskAcc calls the Resource
Manager to read the desk accessory from the resource file.

    You should ignore the value returned by OpenDeskAcc. If the desk
accessory is successfully opened, the function result is its driver
reference number; as described under CloseDeskAcc below, you don't need
this number to close the accessory. If the desk accessory can't be
opened, the function result is undefined; the accessory will have taken
care of informing the user of the problem (such as memory full) and not
displaying itself.

(warning)
         It may occasionally happen that the current grafPort will
         be the desk accessory's port upon return from
         OpenDeskAcc. To be safe, you should bracket your call to
         OpenDeskAcc with calls to the QuickDraw procedures
         GetPort and SetPort, to save and restore the current
         port.

    Before you open a desk accessory it's a good idea to determine
whether there's enough memory available. Here's an example of how to do
that:

        SetResLoad(FALSE);
        myResHandle := GetNamedResource('DRVR', theAcc);
        size := SizeResource(myResHandle);
        myHandle := NewHanddle(size + 3072);
        IF myHandle = NIL
          THEN {put up an alert indicating there's not enough memory}
          ELSE OpenDeskAcc(theAcc)

    The extra 3K bytes in the argument to the Memory Manager's NewHandle
function is an average amount of heap space used by desk accessories
while they're running.
\ CloseDeskAcc
10
PROCEDURE CloseDeskAcc (refNum: INTEGER);

    When a system window is active and the user choses Close from the
File menu, call CloseDeskAcc to close the desk accessory. RefNum is the
driver reference number for the desk accessory, which you get from the
windowKind field of its window.

    The Desk Manager automatically closes a desk accessory if the user
clicks its close box. Also, since the application heap is released
when the application terminates, every desk accessory goes away at that
time.
\ SystemClick
10
PROCEDURE SystemClick (theEvent: EventRecord; theWindow: WindowPtr);

    When a mouse-down event occurs and the Window Manager function
FindWindow reports that the mouse button was pressed in a system
window, the application should call SystemClick with the event record
and the window pointer. If the given window belongs to a desk
accessory, SystemClick sees that the event gets handled properly.

    SystemClick determines which part of the desk accessory's window the
mouse button was pressed in, and responds accordingly (similar to the
way your application responds to mouse activities in its own windows).

  - If the mouse button was pressed in the content region and the
    window and the window was active, SystemClick sends the mouse-down
    event to the desk accessory, which proceses it as appropriate.

  - If the mouse button was pressed in the content region and the
    window was inactive, SystemClick makes it the active window.

  - If the mouse button was pressed in the drag region, SystemClick
    calls the Window Manager procedure DragWindow to pull an outline
    of the window across the screen and move the window to a new
    location. If the window was inactive, DragWindow also makes it
    the active window (unless the Command key was pressed along with
    the mouse button).

  - If the mouse button was pressed in the go-away region, SystemClick
    calls the Window Manager function TrackGoAway to determine whether
    the mouse is still inside the go-away region when the click is
    completed:  if so, it tells the desk accessory to close itself
    otherwise, it does nothing.
\ SystemEdit
10
FUNCTION SystemEdit (editCmd: INTEGER) : BOOLEAN;

    Call SystemEdit when there's a mouse-down event in the menu bar and
the user choses one of the five standard editing commands from the Edit
menu. Pass one of the following as the value of the editCmd parameter:

       EditCmd          Editing command
       0                Undo
       2                Cut
       3                Copy
       4                Paste
       5                Clear


    If your Edit menu contains these five commands in the standard
arrangement (the order listed above, with a gray line separating Undo
and Cut), you can simply call

     SystemEdit(menuItem - 1)

    If the active window dewsn't belong to a desk accessory, SystemEdit
returns FALSE; the application should then process the editing comand
as usual. If the active window dews belong to a desk accessory,
SystemEdit asks that accessory to process the command and returns TRUE;
in this case, the application should ignore the command.

(note)
      It's up to the application to make sure desk accessories 
      get their editing comands that are chosen from the Edit
      menu. In particular, make sure your application hasn't
      disabled the Edit menu or any of the five standard
      commands when a desk accessory is activated.
\ SystemTask
10
PROCEDURE SystemTask;

    For each open desk accessory, SystemTask causes the accessory to
perform the periodic action defined for it, if any such action has been
defined and if the proper time period has passed since the action was
last performed. For example, a clock accessory can be deifined such
that the second hand is to move once every second; the periodic action
for the accessory will be to move the second hand to the next position,
and SystemTask will alert the accessory every second to perform that
action.

    You should call SystemTask as often as possible, usually once every
time through your main event loop. Call it more than once if your
applicaition dies an unusually large amount of processing each time
through the loopk.

(note)
      SystemTask should be called at least every sixtieth of a
      second.



\ SystemEvent
10
FUNCTION SystemEvent (theEvent: EventRecord) : BOOLEAN;

    SystemEvent is called only by the Toolbox Event Manager function
GetNextEvent when it receives an event, to determine whether the event
should be handled by the application or by the system. If the given
event should be handled by the application, SystemEvent returns FALSE;
otherwise, it calls the appropriate system code to handle the event and
returns TRUE.

    In the case of a null, abort, or mouse-down event, SystemEvent does
nothing but return FALSE. Notice that it responds this way to a mouse-
down event even though the event may in fact have occurred in a system
window (and therefore may have to be handled by the system). The
reason for this is that the check for exactly where the event occurred
(via the Window Manager function FindWindow) is made later by the
applicaiton and so would be made twice if SystemEvent were also to do
it. To avoid this duplication, SystemEvent passes the event on to the
application and lets it make the sole call to FindWindow. Should
FindWindow reveal that the mouse-down event did occur in a system
window, the application can then call SystemClick, as described above,
to get the system to handle it.

    If the given event is a mouse-up or keyboard event, SystemEvent
checks whether the active window belongs to a desk accessory and whether
that accessory can handle this type of event. If so, it sends the event
to the desk accessory and returns TRUE; otherwise, it returns FALSE.

(note)
      It's unlikely that a desk accessory would not be set up
      to handle activate and update events.

    Finally, if the given event is a disk-inserted event, SylstemEvent
does some low-level processing (by calling the File Manager function
McountVol) but passes the event on to the application by returning
FALSE, in case the application wants to do further processing.
\ SystemMenu
10
PROCEDURE SystemMenu (menuResult: LONGINT);

    SystemMenu is called only by the Menu Manager functions MenuSelect
and MenuKey, when an item in a menu belonging to a desk accessory has
been chosen. The menuResult parameter has the same format as the value
returned by MenuSelect and MenuKey:  the menu ID in the high-order word
and the menu item number in the low-order word. (The menu ID will be
negative.)  SystemMenu directs the desk accessory to perform the
appropriate action for the given menu item.
\ InfoScrap
11
FUNCTION InfoScrap : PScrapStuff;

    dInfoScrap returns a pointer to information about the desk scrap.
The PScrapStuff data type is defined as follows:

TYPE PScrapStuff = ^ScrapStuff;
     ScrapStuff = RECORD
            scrapSize:    LONGINT;   {size of desk scrap}
            scrapHandle:  Handle;    {handle to desk scrap}
            scrapCount:   INTEGER;   {count changed by ZeroScrap}
            scratState:   INTEGER;   {tells where desk scrap is}
            scrapName:    StringPtr  {scrap file name}
          END;


    ScrapSize is the size of the desk scrap in bytes. ScrapHandle is a
handle to the scrap if it's in memory, or NIL if not.

    ScrapCount is a count that changes every time ZeroScrap is called,
and is useful for testing whether the contents of the desk scrap have
changed during the use of a desk accessory. ScrapState is positive if
the desk scrap is in memory, 0 if it's on the disk, or negative if it
hasn't been initialized by ZeroScrap.

(note)
       ScrapState is actually 0 if the scrap should be on the
       disk; for instance, if the user deletes the Clipboard
       file and then cuts something, the scrap is really in
       memory, but ScrapState will be 0.


    ScrapName is a pointer to the name of the scrap file, usually
"Clipboard File".

(note)
      InfoScrap assumes that the scrap file has a version
      number of 0 and is on the default volume. (Version
      numbers and volumes are described in the File Manager
      manual.)
\ UnloadScrap
1
FUNCTION UnloadScrap : LONGINT;

    UnloadScrap writes the desk scrap from memory to the scrap file, and
relaeses the memory it occupied. If the desk scrap is already on the
disk, UnloadScrap does nothing. If no error occurs, UnloadScrap
returns the result code noErr; otherwise, it returns and Operating
System result code indicating an error.
\ LoadScrap
11
FUNCTION LoadScrap : LONGINT;

    LoadScrap reads the desk scrap from the scrap file into memory. If
the desk scrap is already in memory, it does nothing. If no error
occurs, LoadScrap returns the result code noErr; otherwise, it returns
an Operating System result code indicating an error.
\ GetScrap
11
FUNCTION GetScrap (hDest: Handle; theType: ResType; VAR offset:
                    LONGINT) : LONGINT;

    Given an existing handle in hDest, GetScrap reads the data of type
theType from the desk scrap (whether in memory or on the disk), makes a
copy of it in memory, and sets hDest to be a handle to the copy.
Usually you'll pass in hDest a handle to a minimum-size block; GetScrap
will resize the block and copy the scrap into it. If you pass NIL in
hDest, GetScrap will not read in the data. This is usefull if you want
to be sure the data is there before allocating space for its handle, or
if you just want to know the size of the data.

    In the offset parameter, GetScrap returns the location of the data
as an offset (in bytes) from the beginning of the desk scrap. If no
error occurs, the function result is the length of the data in bytes;
otherwise, it's either an appropriate Operatiing System result code
(which will be negative) or the following Scrap Manager result code:

        CONST noTypeErr = -102;   {no data of the requested type}

For example, given the declaration

        VAR pHndl: Handle;      {handle for 'PICT' type}
        tHndl: Handle;          {handle for 'TEXT' type}
        length: LONGINT;
        offset: LONGINT;

you can make the following calls:

        pHndl := NewHandle(0);
        length := GetScrap(pHandl,'PICT',offset);
        IF length < 0
          THEN
           {error-handling}
          ELSE DrawPicture(PicHandle(pHndl))


    If your application wants data in the form of a  picture, and the
scrap contains only text, you can convert the text into a picture by
doing the following:

          tHndl := NewHandle(0);
          length := GetScrap(tHndl,'TEXT',offset);
          IF length < 0
            THEN
              {error-handling}
            ELSE
              BEGIN
              HLock(tHndl);
              pHndl := OpenPicture(thePort^.portRect);
              TextBox(tHndl^,length,thePort^.portRect,teJustLeft);
              ClosePicture;
              HUnlock(tHndl);
            END


    The Memory Manager procedures HLock and HUnlock are used to lock and
unlock blocks when handles are dereferenced (see the Memory Manager
Manual).

(note)
      To copy the desk scrap to the TextEdit scrap, use the
      TextEdit function TEFromScrap.

    Your application should pass its preferred data type to GetScrap. If
it doesn't prefer one data type over any other, it should try getting
each of the types it can read, and use the type that returns the lowest
offset. (A lower offset means that this data type was written before
the others, and therefore was preferred by the application that wrote
it.)

(note)
      If you're trying to read in a complicated picture, and 
      there isn't enough room in memory for a copy of it, you
      can customize QuickDraw's picture retrieval so that
      DrawPicture will read the picture directly from the scrap
      file. (QuickDraw also lets you customize how pictures
      are saved so you can save them in a file; see the
      QuickDraw manual for details about customizing.)

(note)
      When reading in a picture from the scrap, allow a buffer
      of about 3.5K bytes.  (There's a convention that the
      application defining the picture won't call the QuickDraw
      procedure CopyBits for more than 3K, so a 3.5K buffer
      should be large enough for any picture.
\ ZeroScrap
11
FUNCTION ZeroScrap : LONGINT;

    If the scrap already exists (in memory or on the disk), ZeroScrap
clears its contents; if not, the scrap is initialized in memory. You
must call ZeroScrap before the first time you call PutScrap. If no
error occurs, ZeroScrap returns the result code noErr; otherwise, it
returns an Operating System result code indicating an error.

    ZeroScrap also changes the scrapCount field of the record of
information provided by InfoScrap. This is useful for testing whether
the contents of the desk scrap have changed during the use of a desk
accessory. The application can save the value of the scrapCount field
when one of its windows is deactivated and a system window is
activated. Then, each time through its event loop, it can check to see
whether the value of the field has changed. If so, it means the desk
accessory called ZeroScrap (and, presumable, PutScrap) and thus changed
the contents of the desk scrap.

(warning)
         Just check to see whether the scrapCount field has
         changed; don't rely on exactly how it has changed.
\ PutScrap
11
FUNCTION PutScrap (length: LONGINT; theType: ResType; source: Ptr) :
              LONGINT;

    PutScrap writes the data poointed to by the source parameter to the
desk scrap (in memory or on the disk). The length parameter indicates
the number of bytes to write, and theType is the data type.

(warning)
        The specified type must be different from the type of any
        data already in the desk scrap. If you write data of a
        type already in the scrap, the new data will be appended
        to the scrap, and subsequent GetScrap calls will still
        return the old data.

    If no error occurs, PutScrap returns the result code noErr;
otherwise, it returns an Operating System result code indicating an
error, or the following Scrap Manager result code:

       CONST noScrapErr = -100;  {desk scrap isn't initialized}

(note)
      To copy the TextEdit scrap to the desk scrap, use the
      TextEdit function TEToScrap.

(warning)
       Don't forget to call ZeroScrap to initialize the scrap or
       clear its previous contents.


\ FixRatio
12
FUNCTION FixRatio (numer,demon: INTEGER) : Fixed;

    FixRatio returns the fixed-point quotient of numer and denom. Numer
or denom may be any signed integer. The result is truncated. If denom
is 0, FixRatio returns $7FFFFFFF with the sign of numer.
\ FixMul
12
FUNCTION  FixMul (a,b: Fixed) : Fixed;

    FixMul returns the fixed-point product of a and b. The result is
computed MOD 65536, and truncated.
\ FixRound
12
FUNCTION FixRound (x: Fixed) : INTEGER;

    Given a positive fixed-point number, FixRound rounds it to the
nearest integer and returns the result. If the value is halfway between
two integers (.5), it's rounded up. To round a negative fixed-point
number, multiply by -1, round, then multiply by -1 again.
\ NewString
12
FUNCTION NewString (theString: Str255) : StringHandle;

    NewString allocates the specified string as a relocatable object on
the heap and returns a handle to it.
\ SetString
12
PROCEDURE SetString (h: StringHandle; theString: Str255);

    SetString sets the string whose handle is passed in h to the string
specified by theString.
\ GetString
12
FUNCTION GetString (stringID: INTEGER) : StringHandle;

    GetString returns a handle to the string having the given resource
ID, reading it from the resource file if necessary. It calls the
Resource Manager function GetResource('STR ',stringID). If the resource
can't be read, GetString returns NIL.

(note)
      If your application uses a large number of strings,
      storing them in a string list in the resource file will
      be more efficient. You can access strings in a string
      list with GetIndString, as described below.
\ GetIndString
12
PROCEDURE GetIndString (VAR theString: Str255; strListID: INTEGER;
             Index: INTEGER);    [No trap macro]

    GetIndString returns in theString a string in the string list that
has the resource ID strListID. It reads the string list from the
resource file if necessary, by calling the Resource Manager function
GetResource('STR#',strListID). It returns the string specified by the
index parameter, which can range from 1 to the number of strings in the
list. If the resource can't be read or the index is out of range, the 
empty string is returned.
\ Munger
12
FUNCTION Munger (h: Handle; offset: LONGINT; ptrl: Ptr; lenl: LONGINT;
                    ptr2: Ptr; len2: LONGINT) : LONGINT;

    Munger (which rhymes with "plunger") lets you manipulate bytes in
the string of bytes (the "destination string") to which h is a handle.
The operation starts at the specified byte offset in the destination
string.

(note)
      Although the term "string" is used here, Munger does not
      assume it's manipulating a Pascal string; if you pass it
      a handle to a Pascal string, you must take into account
      the length byte.

    The exact nature of the operation done by Munger depends on the
values you pass it in two pointer/length parameter pairs. In general,
(ptr1,len1) defines a target string to be replaced by the second string
(ptr2,len2). If these four parameters are all positive and nonzero,
Munger looks for the target string in the destination string, starting
from the given offset and ending at the end of the string; it replaces
the first occurrence it finds with the replacement string and returns
the offset of the first byte past where the replacement occurred.
Figure 1 illustrates this; the bytes represent ASCII characters as
shown.

    Different operations occur if either pointer is NIL or either length
is 0:

    - If ptr1 is NIL, the substring of length len1 starting at the given
      offset is replaced by the replacement string. If len1 is
      negative, the substring from the given offset to the end of the
      destination string is replaced by the replacement string. In
      either case, Munger returns the offset of the first byte past
      where the replacement occurred.


    - If len1 is 0, (ptr2,len2) is simply inserted at the given offset;
      no text is replaced. Munger returns the offset of the first byte
      past where the insertion occurred.

    - If ptr2 is NIL, Munger returns the offset at which the targer
      string was found. The destination string isn't changed.

    - If ptr2 is NIL, Munger returns the offset at which the target
      string was found. The destination string isn't changed.

    - If len2 is 0 (and ptr2 is not NIL), the target string is deleted
      rather than replaced (since the replacement string is empty).
      Munger returns the offset at which the deletion occurred.


    If it can't find the target string in the destination string, Munger 
returns a negative value.

    There's one case in which Munger performs a replacement even if it
doesn't find all of the target string. If the substring from the
offset to the end of the destination string matches the beginning of
the target string, the portion found is replaced with the replacement
string.

(warning)
        Be careful not to specify an offset that's greater than
        the length of the destination string, or unpredictable
        results may occur.

(note)
        The destination string must be in a relocatable block
        that was allocated by the Memory Manager. Munger
        accesses the string's length by calling the Memory
        Manager routines GetHandleSize and SetHandleSize.
\ PackBits
12
PROCEDURE PackBits (VAR srcPtr,DstPtr: Ptr; srcBytes: INTEGER);

    PackBits compresses srcBytes bytes of data starting at srcPtr and
stores the compressed data at dstPtr. The value of srcBytes should not
be greater than 127. Bytes are compressed when there are three or more
consecutive equal bytes. After the data is compressed, srcPtr is
incremented by srcBytes and dstPtr is incremented by the number of
bytes that the data was compressed to. In the worst case, the
compressed data can be one byte longer than the original data.

    PackBits is usually used to compress QuickDraw bit images; in this
case, you should call it for one row at a time. (Because of the
repeating patterns in QuickDraw images, there are more likely to be
consecutive equal bytes there than in other data.)  Use UnpackBits
(below) to expand data compressed by PackBits.
\ UnpackBits
12
PROCEDURE UnpackBits (VAR SrcPtr, DstPtr: Ptr; dstBytes: Integer);

    Given in SrcPtr a pointer to the data that was compressed by PackBits,
UnpackBits expands the data and stores the result as DstPtr. DstBytes is
the length that the expanded data will be; it should be the value that was
passed to PackBits in the SrcBytes parameter. After the data is expanded,
srcPtr is incremented by the number of bytes that were expanded and dstPtr
is incremented by dstBytes.
\ BitTst
12
FUNCTION BitTst (BytePtr: Ptr; bitNum: Longint): Boolean;

    BitTst tests wether a given bit is set and returns TRUE if so or FALSE
if not. The bit is specified by bitNum, an offset from the high-order bit
of the byte pointed to by BytePtr.
\ BitSet
12
PROCEDURE BitSet (BytePtr: Ptr; bitNum: Longint);

    BitSet sets the bit specified by bitNum, an offset from the high-order
bit of the byte pointed to by BytePtr.
\ BitClear
12
PROCEDURE BitClear (BytePtr: Ptr; bitNum: Longint);

    BitClear clears the bit specified by bitNum, an offset from the
high-order bit of the byte pointed to by BytePtr.
\ BitAnd
12
FUNCTION BitAnd (Value1, Value2: Longint): Longint;

    BitAnd returns the value of the AND logical operation on the bits
comprising the given long integers ( vallue1 AND value2).
\ BitOr
12
FUNCTION BitOr (Value1, Value2: Longint): Longint;

    BitOr returns the value of the OR logical operation on the bits
comprising the given long integers ( vallue1 OR value2).
\ BitXor
12
FUNCTION BitXor (Value1, Value2: Longint): Longint;

    BitXor returns the value of the XOR logical operation on the bits
comprising the given long integers ( vallue1 XOR value2).
\ BitNot
12
FUNCTION BitNot (Value: Longint): Longint;

    BitNot returns the result of the NOT logical opeation on the bits
comprisisng the given long integer (NOT value).
\ BitShift
12
FUNCTION BitShift (Value: Longint; count: Integers): Longint;

    BitShift logically shifts the bits of the giveb long integer. The count
parameter specifies the direction and the extent of the shift, and is token
MOD 32. If count is positive, BitShift shifts that many positions to the
left; if count is negative, it shifts to the right. Zeroes are shifted into
empty positions at their end.
\ HiWord
12
FUNCTION HiWord (x: Longint): Integer;

    HiWord returns the high-order word of the given long integer. One use
of this function is to extract the integer part of a fixed-point number.
\ LoWord
12
FUNCTION LoWord (x: Longint): Integer;

    LoWord returns the low-order word of the given long integer. One use
of this function is to extract the fractional part of a fixed-point number.

    Note: If you're dealing with a long intger that contains two separate
    integer values, you can define a variant record instead of using
    HiWord and LoWord. For example, for fixed-point numbers, you can define
    the following type:

      TYPE FixedAndInt = RECORD CASE Integer OF
                            1: (FixedView: Fixed);
                            2: (intView:   RECORD
                                            Whole: Integer;
                                            Part : Integer;
                                           END;)
                          END;

    If you declare x to be of type FixedAndInt, you can access it as a
    fixed-point value with x.FixedView, or access the integer part with
    x.intView.Whole aand the fractional part with x.intView.part.
\ LongMul
12
PROCEDURE LongMul (a,b: Longint; VAR dest: Int64bit);

    LongMul multiplies the given long integers and returns the signed
result in dest which has the following data type:

    TYPE Int64Bit = RECORD
                      HiLong: Longint;
                      LoLong: Longint;
                    END;
\ ScreenRes
12
PROCEDURE ScreenRes (VAR scrnHRes, scrnVRes: Integer); [Not in ROM]

    ScreenRes returns the resolution of the screen of the macintosh being
used. ScrnHRes and scrnVRes are the number of pixels per inch horizontally
and verticaly, respectively.

        ____________________________________________________________
         Assembly-language note: The number of pixels per  inch
         horizontally is stored in the global variable ScrHRes, and
         the number of pixels per inch vertically is stored in
         ScrVRes.
        ____________________________________________________________
\ GetIcon
12
FUNCTION GetIcon (IconId: Integer): Handle;

    GetIcon returns a handle to the icon having the given resource ID,
reading it from the resource file if necessary. It calls the resource
manager function GetResource ('ICON', IconId). If the resource can't be
read, GetIcon returns NIL.
\ PlotIcon
12
PROCEDURE PlotIcon (TheRect: Rect; TheIcon: Handle);
    PlotIcon draws the icon whose handle is theIcon in the rectangle
TheRect, which is in the local coordinate of the current grafport. It calls
the QuickDraw procedure CopyBits and uses the srcCopy transfer mode.
\ GetPattern
12
FUNCTION GetPattern (PatID: Integer): PatHandle;

    GetPattern returns a handle to the pattern  having the given resource
ID, reading it from the resource file if necessary. It calls the resource
manager function  GetResource ('PAT ', PatId). If the resource can't be
read, GetPattern returns NIL. The PatHandle data type is defined in the
toolbox utilities as follows:

    TYPE  PatPtr    = ^Pattern;
          PatHandle = ^PatPtr;
\ GetIndPattern
12
Function GetIndPattern (VAR ThePattern: Patter; PatLisId: Integer; Index:
                        Integer);  [Not in ROM]

    GetIndPattern returns in the pattern a pattern in the pattern list that
has the resource ID PatListID. It reads the pattern list from the resource
file if necessary, by calling the Resource Manager function
GetResource ('PAT#', PatListID). It returns the pattern specified by the
index parameter, which can range from 1 to the number of patterns in the
pattern list.

    There's a pattern list in the system resource file that contains the
standard Macintosh patterns used by MacPaint. Its resource ID is :

    CONST   SysPatListID = 0;
\ GetCursor;
12
FUNCTION GetCursor (CursorID: Integer): CursHandle;

    GetCursor returns a handle to the cursor having the given resource ID,
reading it forme the resource file if necessary. It calls the resource
manager function GetResource ('CURS', CursorIdD). If the resource can't be
read, GetCursor returns NIL. The CursHandle data type is defined in the
toolbox utilities as follows:

    TYPE    CursPtr    = ^Cursor;
            CursHandle = ^CursPtr;

    The standard cursors are defined in the system resource file. Their
resources ID are:

    CONST   iBeamCursor = 1; {to select text}
            crossCursor = 2; {to draw graphics}
            plusCursor  = 3; {to select cells in structured documents}
            watchCursor = 4; {to indicate a too long wait}


    Note: You can set the cursor with the quickdraw procedure SetCursor.
    The arrow cursor is defined in QuickDraw as a global variable named
    Arrow.
\ ShieldCursor
12
PROCEDURE ShieldCursor (shieldRect: Rect; OffsetPt: Point);

    If the cursor and the given rectangle intersect, ShieldCursor hides the
cursor. If they don't intersect, the cursor remains visible while the mouse
isn't moving, but is hidden when the mouse moves.

    Like the QuickDraw procedure HideCursor, ShieldCursor decrements the
cursor level,  and should be balanced by a call to ShowCursor.

    The rectangle may be given in local or global coordinates:

Ĩ  If they're global coordinates, pass (0, 0) in OffsePt.
Ĩ  If they're a grafport's local coordinates, pass the top left corner of
   the grafport's boundary rectangle in OffsetPt. (Like the QuickDraw
   procedure LocalToGlobal, ShieldCursor will offset the coordinates of
   the rectangle by the coordinate of this point.)
\ GetPicture
12
FUNCTION GetPicture (PicID: Integer): PicHandle;

    GetPicture returns a handle to the picture having the given resource
ID, reading it from the resource file if necessary. It calls the resource
Manager function GetResource ('PICT', PicID). If the resource can't be read
GetPicture returns NIL. The PicHandle data type is defined in QuickDraw.
\ DeltaPoint
12
FUNCTION DeltaPoint (ptA, ptB: Point): Longint;

    DeltaPoint substracts the coordinates of ptB from the coordinates of
ptA. The high-order word of the result is the difference of the vertical
coordinates, and the low-order word is the difference of the horizontal
coordinates.

    NOTE : The QuickDraw procedure SubPt also substracts the coordinates
    of one point, but returns the result in a VAR parameter of type Point.
\ SlopeFromAngle
12
FUNCTION SlopeFromAngle (Angle: Integer): Fixed;

    Given an angle, SlopeFromAngle returns the slope dh/dv of the line
forming that angle with the Y-axis (dh/dv is the horizontal change divided
by the vertical  change between any two points on the line). The angle is
treated MOD 180, and its degrees measured from 12 o'clock; positive degrees
are measured clockwise, negative degrees are measured counterclockwise (for
example, 90 degrees is at 3 o'clock, and -90 degrees is at 9 o'clock).
Positive y is down; positive x is to the right.
\ AngleFromSlope
12
Function AngleFromSlope (Slope: Fixed): Integer;

    Given the slope dh/dv of a line (see SlopeFromAngle), AngleFromSlope
returns the angle formed by that line and the y-axis. The angle returned
is between 1 and 180 (inclusive), in degrees measured clockwise from 12
o'clock.

    AngleFromSlope is meant for use when speed is much more important than
accuracy - its integer result is guaranted to be one degree of the correct
answer,  but not necessarily within half a degree. However the equation

    AngleFromSlope(SlopeFromAngle(x))= x

is true for all x except 0 (although reverse is not).

    NOTE : SlopeFromAngle(0) is 0, and AngleFromSlope(0) is 180.
\ FracMul
12
FUNCTION FracMul (x,y: Fract) : Fract;

FracMul returns x * y. Note that FracMul effects

Ōtype   *   Fract   Ņ>  typeĶ:
Fract   *   Fract   Ņ>  Fract
LONGINT *   Fract   Ņ>  LONGINT
Fract   *   LONGINT Ņ>  LONGINT
Fixed   *   Fract   Ņ>  Fixed
Fract   *   Fixed   Ņ>  Fixed
\FixDiv
12
FUNCTION FixDiv (x,y: Fixed) : Fixed;

FixDiv returns x / y.
\FracDiv
12
FUNCTION FracDiv (x,y: Fract) : Fract;

FracDiv returns x / y.
\FracSqrt
12
FUNCTION FracSqrt (x: Fract) : Fract;
    FracSqrt returns the square root of x, with x interpreted as
unsigned in the range 0 through 4Đ(2Đ30), inclusive:  That is, bit 15 in
Figure 1 has weight 2 rather than Đ2. The result, too, is unsigned
in the range 0 through 2, inclusive.
\FracCos
12
FUNCTION FracCos (x: Fixed) : Fract;
    FracCos and FracSin return the cosine and sine of their radian
arguments, respectively. The hexadecimal value 0.C910 (which is
FixATan2(1,1)) is the approximation to š/4 used for argument reduction.
Thus, FracCos and FracSin are nearly periodic, but with period 2*P
instead of 2*š, where P=3.1416015625 and š, of course, is 3.14159265....
\FracSin
12
FUNCTION FracSin (x: Fixed) : Fract;

    FracCos and FracSin return the cosine and sine of their radian
arguments, respectively. The hexadecimal value 0.C910 (which is
FixATan2(1,1)) is the approximation to š/4 used for argument reduction.
Thus, FracCos and FracSin are nearly periodic, but with period 2*P
instead of 2*š, where P=3.1416015625 and š, of course, is 3.14159265....
\FixATan2
12
FUNCTION FixATan2 (x,y: LONGINT) : Fixed;

    FixATan2 returns the arctangent of y / x in radians.
\Long2Fix
12
FUNCTION Long2Fix (x: LONGINT) : Fixed;

    Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between
fixed-point types.
\Fix2Long
12
FUNCTION Fix2Long (x: Fixed) : LONGINT;

Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point
types.
\Fix2Frac
FUNCTION Fix2Frac (x: Fixed) : Fract;

Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point
types.
\Frac2Fix
12
FUNCTION Frac2Fix (x: Fract) : Fixed;

Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point
types.

\Fix2X
12
FUNCTION Fix2X  (x: Fixed) : Extended;

Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract
and the Extended floating-point type. These functions do not set
floating-point exception flags.
\X2Fix
12

Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract
and the Extended floating-point type. These functions do not set
floating-point exception flags.
FUNCTION X2Fix  (x: Extended) : Fixed;
\Frac2X
12
FUNCTION Frac2X (x: Fract) : Extended;

Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract
and the Extended floating-point type. These functions do not set
floating-point exception flags.
\X2Frac
12
FUNCTION X2Frac (x: Extended) : Fract;

Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract
and the Extended floating-point type. These functions do not set
floating-point exception flags.

\ InitPack
13
PROCEDURE InitPack (packID: INTEGER);

    InitPack enables you to use the package specified by packID, which
is the package's resourceID. (It gets a handle that will be used later
to read the package into memory.)
\ InitAllPacks
13
PROCEDURE InitAllPacks;

    InitAllPacks enables you to use all Macintosh packages (as though
InitPack were called for each one). It wil already have been called
when your application starts up.
\ IUDateString
13
PROCEDURE IUDateString (dateTime: LongInt; form: DateForm; VAR result:
                        Str255);

    Given a date and time as returned by the Operating System Utility
routine ReadDateTime, IUDateString returns in the result parameter a
string that represents the corresponding date. The form parameter has
the following data type:

       TYPE DateForm = (shortDate,longDate,abbrevDate);

    ShortDate requests the short date format, longDate the long date,
and abbrevDate the abbreviated long date. IUDateString determines the
exact format from international resource 0 for the short date of 1 for
the long date. See Figure I-1 above for examples of the standard
formats. Notice that the short date contains a space in place of  a
leading zero when the format specifies "no leading zero", so the length
of the result is always the same for short dates.

    If the abbreviated long date is requested and the abbreviation
length in international resource 1 is greater than the actual length of
the name being abbreviated, IUDateString fills the abbreviation with NUL
characters; the abbreviation length should not be greater than 15, the
maximum name length.
\ IUDatePString
13
PROCEDURE IUDatePString (dateTime: LongInt; form: DateForm; VAR result:
            Str255; intlParam: Handle);


    IUDatePString is the same as IUDateString except that it determines
the exact format of the date from the resource whose handle is passed in
intlParam, overriding the resource that would otherwise be used.
\ IUTimeString
13
PROCEDURE IUTime STring (dateTime: LongInt; wantSeconds: BOOLEAN; VAR
            result: Str255);

    Given a date and time as returned by the Operating System Utility
routein ReadDateTime, IUTimeString returns in the result parameter a
string that represents the corresponding time of day. If wantSeconds
is TRUE, seconds are included in the time; otherwise, only the hour and
minute are included. IUTimeSting determines the time format from
internation resource 0. See Figure I-1 above for examples of the
standard formats. Notice that the time contains a space in place of a
leading zero when the format specifies "no leading zero", so the length
of the result is always the same.
\ IUTimePString
13
PROCEDURE IUTimePString (dateTime: LongInt; wantSeconds: BOOLEAN; VAR
            result: str255; intlParam: Handle);

    IUTimePString is the same as IUTimeString except that it determines
the time format from the resource whose handle is passed in intlParam,
overriding the resource that would otherwise be used.
\ IUMetric
13
FUNCTION IUMetric : BOOLEAN;

    If international resource 0 specifies that the metric system is to
be used, IUMetric retruns TRUE; otherwise, it returns FALSE.
\ IUGetIntl
13
FUNCTION IUGetIntl (theID: INTEGER) : Handle;

    IUGetIntl returns a handle to the international resource numbered
theID (0 or 1). It calls the Resource Manager function
GetResource('INTL',theID). For example, if you want to access
individual fields of international resource 0, you can do the
following:

     VAR myHndl: Handle;
         int0: Intl0Hndl;
     ...
     myHndl := IUGetIntl(0);
     int0 := POINTER(ORD(myHndl));
\ IUSetIntl
13
PROCEDURE IUSetIntl (refNum: INTEGER; thefID; INTEGER; intlParam:
            Handle);

    In the resource file having the reference number refNum, IUSetIntl
sets the international resource numbered theID (0 or 1) to the data
pointed to by tintlParam. The data may be either an existing resource
okr data that hasn't yet been written to a resource file. IUSetIntl
adds the resource to the specified file or replaces the resource if it's
already there.
\ IUCompString
13
FUNCTION IUCompString (aStr,bStr: Str255) : INTEGER;  [Pascal only]

    IUCompString compares aStr and bStr as described above under
"International String Comparison", taking both primary and secondary
ordering into consideration. It returns one of the values listed
below.

      Result   Meaning                           Example
                                              aStr     bStr
       -1       aStr is less than bStr       'Ab'     'ab'
        0       aStr  equals bStr            'Ab'     'Ab'
        1       aStr is greater than bStr    'Ac'     'ab'
\ IUMagString
13
FUNCTION IUMagString (aPtr,bPtr: Ptr; aLen,bLen: INTEGER) : INTEGER;

    IUMagString is the same as IUCompString (above) except that instead
of comparing two Pascal strings, it compares the string defined by aPtr
and aLen to the string defined by bPtr and bLen. The pointer points to
the first character of the string (any byte in memory, not necesarily
word-aligned), and the length specifies the number of characters in the
string.
\ IUEqualString
13
FUNCTION IUEqualString (aStr,bStr: Str255) : INTEGER;   [Pascal only]

    IUEqualString comapares aStr and bStr for equality without regard
for secondary ordering, as described above under "international String
Comparison". If the strings are equal, it returns 0; otherwise, it
returns 1. For example, if the strings are 'Rose' and 'rose',
IUEqualString considers them equal and returns 0.

(note)
      See also EqualString in the Operating System Utilities
      manual *** doesn't yet exist***.
\ IUMagIDString
13
    IUMagIDString is the same as IUEqualString (above) except that
instead of comparing two Pascal strings, it compares the string defined
by aPtr and aLen to the string defined by bPtr and bLen. The pointer
points to the first character of the string (any byte in memory, not
necessarily word-aligned), and the length specifies the number of4
characters in the string.
\ NumToString
13
PROCEDURE NumToString (theNum: LongInt; VAR theStringd: Str255);

____________________________________________________________________

Trap macro     _NumToString

On entry       A0:  pointer to theString (length byte followed
                  by characters)

             D0:  theNum (long integer)

On exit         A0:  pointer to theString

_____________________________________________________________________

    NumToString converts theNum to a string that represents its decimal
value, and returns the result in theString. If the value is negative,
the string begins with a minus sign; otherwise, the sign is omitted.
Leading zeroes are suppressed, except that the value 0 produces '0'.
For example:

     theNum          theString
      12              '12'
     -23             '-23'
       0              '0'
\ StringToNum
13
PROCEDURE StringToNum (theString: Str255; VAR theNum: LongInt);

___________________________________________________________________

Trap macro     _StringToNum

On entry       A0:  pointer to theString (length byte followed
                  by characters)

On exit        DO:  theNum (long integer)

___________________________________________________________________


    Given a string representing a decimal integer, StringToNum converts
it to the corresponding integer and returns the result in theNum. The
string may begin with a plus or minus sign. For example:

      theString          theNum
        '12'               12
       '-23'              -23
        '-0'                0
       '055'               55

    The magnitude of the integer is converted modulo 2^32, and the
32-bit result is negated if the string begins with a minus sign; integer
overflow occurs if the magnitude is greater than 2^31-1. (Negation is
done by taking the two's complement--reversing the state of each bit
adn then ading 1.)  For example:

        theString                                   theNum
       '2147483648'  (magnitude is 2^31)          -2147483648
      '-2147483648'                               -2147483648
       '4294967295'  (magnitude is 2^31)              -1
      '-4294967295'                                    1

    StringToNum doesn't actually check whether the characters in the
string are between '0' and '9'; instead, since the ASCII codes for '0'
through '9' are $30 through $39, it just masks off the last four bits
and uses them as a digit. For example, '2:' is converted to the number
30 because the ASCI code for ':' is $3A. Leading spaces before the
first digit are treated as zeroes, since the ASCII code for a space is
$20. Given that the ASCII codes for 'C', 'A', and 'T' are $43, $41, and
$54, respectively, consider the following examples:


      theString              theNum
        'CAT'                  314
       '+CAT'                  314
       '-CAT'                 -314
\ SFPutFile
13
PROCEDURE SFPutFile (where: Point; prompt: Str255; origName: Str255;
                    dlgHook: ProPtr; VAR reply: SFReply);

    SFPutFile displays a dialog box allowing the user to specify a file
to which data will be written (as during a Save or Save As command). It
then repeatedly gets and handles events until the user either confirms
the command after entering an appropriate file name or aborts the
command by clicking Cancel in the dialog. It reports the user's reply
by filling the fields of the reply record specified by the reply
parameter, as described above; the fType field of this record isn't
used.

    The general appearance of the standard SFPutFile dialog box is shown
in Figure S-2. The where parameter specifies the location of the top
left corner of the dialog box in global coordinates. The prompt
parameter is a line of text to be displayed as a statText item in the
dialog box, where shown in Figure S-2. The origName parameter contains
text that appears as an enabled, selected editText item; for the
standard document-saving commands, it should be the current name of the
document, or the empty string (to display an insertion point) if the
document hasn't been named yet.

    If you want to use the standard SFPutFile dialog box, pass NIL for
dlgHook; otherwise, see the information for advanced programmers below.

    SFPutFile  repeatedly calls the Dialog Manager procedure
ModalDialog. When an event involving an enabled dialog item occurs,
ModalDialog handles the event andf returns the item number, and
SFPutFile responds as follows:

   - If the Eject or Drive button is clicked, or a disk is inserted,
     SFPutFile responds as described above under "About the Standard
     File Package".

   - Text entered into the editText item is stored in the fName field
     of the reply record. (SFPutFile keeps track of whetehr there's
     currently any text in the item, and makes the Save button inactive
     if not.)

   - If the Save button is clicked, SFPutFile determines whether the
     file name in the fName field of the reply record is appropriate.
     If so, it returns control to the application with the first field
     of the reply record set to TRUE; otherwise, it responds
     accordingly, as described below.

  - If the Cancel button in the dialog is clicked, SFPutFile returns
    control to the application with the first field of the reply
    record set to FALSE.

(note)
       Notice that disk insertion is one of the user actions
       listed above, even though ModalDialog normally ignores
       disk-inserted events. The reason this works is that
       SFPutFile calls ModalDialog with a filterProc function
       that checks for a disk-inserted event and returns a
       "fake", very large item number if one occurs; SFPutFile
       recognizes this item number as an indication that a disk
       was inserted.

    The situations that may cause an entered name to be inappropriate,
and SFPutFile's response to each, are as follows:

     - If a file with the specified name already exists on the disk and
       is different from what was passed in the origName parameter, the
       alert in Figure S-3 is displayed. If the user clicks Yes, the
       file name is appropriate.

     - If the disk to which the file shoud be written is locked, the
       alert in Figure S-4 is displayed. If a system error occurs, a
       similar alert is displayed, with a corresponding message
       explaining the problem.

(note)
       The user may specify a disk name (preceding the file name
       and separated from it by a colon). If the disk isn't
       currently in a drive, an alert similar to the one in
       Figure S-4 is displayed. The ability to specify a disk
       name is supported for historical reasons only; users
       should not be encouraged to do it.

    After the user clicks No or Cancel in response to one of these
alerts, SFPutFile dismisses the alert box and continues handling events
(so a different name may be entered).

Advanced programmers:  You can create your own dialog box rather than
use the standard SFPutFile dailog. To do this, you must provide your
own dialog template and store it in your application's resource file
with the same resource ID that the standard template has in the system
resource file:

        CONST putDlgID = -3999;   {SFPutFile dialog template ID}

(note)
       The SFPPutFile procedure, described below lets you use
       any resource ID for your nonstandard dialog box.

    Your dialog template must specify that the dialog window be
invisible, and your dialog must contain all the standard items, as
listed below. The appearance and location of these items in your dialog
may be different. You can make an item "invisible" by giving it a
display rectangle that's off the screen. The display rectangle for each
item in the standard dialog box is given below. The rectangle for the
standard dialog box itself is (0,0,304,104).


   Item Number  Item                     Standard display rectangle
    1       Save button                  (12,74,82,92)
    2       Cancel button                (114,74,184,92)
    3       Prompt string (statText)     (12,12,184,28)
    4       UserItem for disk name       (209,16,295,34)
    5       Eject button                 (217,43,287,61)
    6       Drive button                 (217,74,287,92)
    7       EditText item for file name  (14,34,182,50)
    8       UserItem for gray line       (200,16,201,88)


(note)
       Remember that the display rectangle for any "invisible"
       item must be at least about 20 pixels wide. *** This
       will be discussed in a future draft of the Dialog Manager
       manual. ***


    If your dialog has addition items beyond the standard ones, or if
you want to handle any of the standard items in a nonstandard manner,
you must write your own dlgHook funciton and point to it with dlgHook.
Your dlgHook function should have two parameters and return an integer
value. For example, this is how it wokuld be declared if it were named
MyDlg:

       FUNCTION MyDlg (item: INTEGER; theDialog: DialogPtr) : INTEGER;

    Immediately after calling ModalDialog, SFPutFile calls your dlgHook
function, passing it the item number returned by ModalDialog and a
pointer to the dialog record describing your dialog box. Using these
two parameters, your dlgHook function should determine how to handle
the event. There are predefined constants for the item numbers of
standard enabled items, as follows:

      CONST putSave   = 1;   {Saver button}
            putCancel = 2;   {Cancel button}
        putEject  = 5;   {Eject button}
        putDrive  = 6;   {Drive button}
        putName   = 7;   {editText item for file name}

    ModalDialog also returns the "fake" item number 100 when a disk-
inserted event occurs, as detected by its filterProc function.

    After handling the event (or, perhaps, after ignoring it) the
dlgHook function must return an item number to SFPutFile. If the item
number is one of those listed above, SFPutFile responds in the standard
way; otherwise, it does nothing.

(note)
       For advanced programmers who want to change the
       appearance of the alerts displayed when an inappropriate
       file name is entered, the resource IDs of those alerts in
       the system resource file are listed below.


       Alert                   Resource ID
       Existing file             -3996
       Locked disk               -3997
       System error              -3995
       Disk not found            -3994
\ SFPPutFile
13
PROCEDURE SFPPutFile (where: Point; prompt: SStr255; origNmae: Str255;
             dlgHook: ProcPtr; VAR reply: SFReply; dlgID: INTEGER;
         filterProc: ProcPtr);

    SFPPutFile is an alternative to SFPutFile for advanced programmers
who want to use a nonstandard dialog box. It's the same as SFPutFile
except for the two additional parameters dlgID and filterProc.

    DlgID is the resource ID of the dialog template to be used instead
of the standard one (so you can use whatever ID you wish rather than the
same one as the standard).

    The filterProc parameter determines how ModalDialog will filter
events when called by SFPPutFile. If filterProc is NIL, ModalDialog
does the standard filtering that it does when called by SFPutFile;
otherwise, filterProoc should point to a function for ModalDialog to
execute afterdoing the standard filterilng. THe function must be the
same as one you'd pass directly to ModalDialog in its filterProc
parameter. (See the Dialog Manager manual for more information.)
\ SFGetFile
13
PROCEDURE SFGetFile (where: Point; prompt: Str255; fileFilter: ProcPtr;
                    numTypes: INTEGER; typeList: SFTypeList;
                    dlgHook: ProcPtr; VAR reply: SFReply);

    SFGetFIle displays a dialog box listing the names of a specific
group of files from which the user can select one to be opened (as
during an Open command). It then repeatedly gets and handles events
until the user either confirms the command after choosing a file name or
aborts the command by clicking Cancel in the dialog. It reports the
user's reply by filling the fields of the reply record specified by the
reply parameter, as described above under "Using the Standard File
Package".

    The general appearance of the standard SFGetFile dialog box is shown
in Figure S-5. File names are sorted in order of the ASCII codes of
their characters, ignoring diacritical marks and mapping lowercase
characters to their uppercase equivalents. If there are more file names
than can be displayed at one time, the scroll bar is active; otherwise,
the scroll bar is inactive.

    The where parameter specifies the  location of the top left corner
of the dialog box in global coordinates. The prompt parameter is
ignored; it's there for historical purposes only.

    The fileFilter, numTypes, and typeList parameters determine which
files appear in the dialog box. SFGetFile first looks at numTypes and
typeList to determine what types of files to display, then it executes
the function pointed to by fileFilter (if any) to do additional
filtering on which files to display. File types are discussed in the
manual THE STRUCTURE OF A MACINTOSH APPLICATION. For example, if the
applicaiton is concerned only with pictures, you won't want to display
the names of any text files.

    Pass -1 for numTypes to display all types of files; otherwise, pass
the number of file types you want to display, and pas the types
themselves in typeList. The SFTypeList data type is defined as follows:

         TYPE SFTypeList = ARRAY [0..3] OF OSTYPE;

(note)
       This array is declared for a reasonable maximum number of
       types (four). If you need to specify more than four
       types, declare your own array type with the desired
       number of entries (and use the @ operator to pass a
       pointer to it).

    If fileFilter isn't NIL, SFGetFile executes the function it points
to for each file, to determine whether the file should be displayed.
The fileFilter function has one parameter and returns a Boolean value.
For example:

         FUNCTION MyFileFilter (paramBlock: ParmBlkPtr) : BOOLEAN;

    SFGetFile passes this function the file information it gets by
calling the File Manager procedure PBGetFInfo. The function selects
which files should appear in the dialog by returning FALSE for every
file that should be shown and TRUE for every file that shouldn't be
shown.

(note)
       As described in the File Manager manual, a flag can be
       set that tells the Finder not to display a particular
       file's icon on the desktop; this has no effect on whether
       SFGetFile will list the file name.

    If you want to use the standard SFGetFile dialog box, pass NIL for
dlgHook; otherwise, see the information for advanced programmers below.

    Like SFPutFile, SFGetFile repeatedly calls the Dialog Manager
procedure ModalDialog. When an event involving an enabled dialog item
occurs, ModalDialog handles the event and returns the item number, and
SFGetFile responds as follows:

   - If the Eject or Drive button is clicked, or a disk is inserted,
     SFGetFile responds as described above under "About the Standard
     File Package".

   - If clicking or dragging occurs in the scroll bar, the contents of
     the dialog box are redrawn accordingly.

   - If a file name is clicked, it's selected and stored in the fName
     field of the reply record. (SFGetFile keeps track of whether a
     file name is currently selected, and makes the Open button
     inactive if not.)

   - If the Open button is clickd, SFGetFile returns control to the
     application with the first field of the reply record set to TRUE.

   - If a file name is double-clicked, SFGetFile responds as if the
     user clicked the file name and then the Open button.

   - If the Cancel button in the dialog is clicked, SFGetFile returns
     control to the application with the first field of the reply
     record set to FALSE.

    If a key (other than a modifier key) is pressed, SFGetFile selects
the first file name starting with the character typed. If no file name
starts with that character, it selects the first file name starting
with a character whose ASCII code is greater than the character typed.

Advanced programmers:  You can create your own dialog box rather than
use the  standard SFGetFile dialog. To do this, you must provide your
own dialog template and store it in your application's resource file
with the same resource ID that the standard template has in the system
resource file:

        CONST getDlgID = -4000;   {SFGetFile dialog template ID}

(note)
      THe SFPGetFile procedure, described below, lets you use
      any resource ID for your nonstandard dialog box.


    Your dialog template must specify that the dialog window be
invisible, and your dialog must contain all the standard items, as
listed below. The appearance and location of these items in your dialog
may be different. You can make an item "invisible" by giving it a
display rectangle that's off the screen. The display rectangle for each
in the standard dialog box is given below. THe rectangle for the
standard dialog box itself is (0,0,348,136).

 Item Number    Item                     Standard display rectangle
    1         Open button                     (152,28,232,46)
    2         Invisible button                (1152,59,1232,77)
    3         Cancel button                   (152,90,232,108)
    4         UserItem for disk name          (248,28,344,46)
    5         Eject button                    (256,59,336,77)
    6         Drive button                    (256,90,336,108)
    7         UserItem for file name list     (12,11,125,125)
    8         UserItem for scroll bar         (124,11,140,125)
    9         UserItem for gray line          (244,20,245,116)
   10         Invisible text (statText)       (1044,20,1145,116)

    If your dialog has additional items beyond the standard ones, or if
you want to handle any of the standard items in a nonstandard manner,
you must write your own dlgHook function and point to it with dlgHook.
Your dlgHook function should have two parameters and return an integer
value. For example, this is how it would be declared if it were named
MyDlg:

       FUNCTION MyDlg (item: INTEGER; theDialog: DialogPtr) : INTEGER;

    Immediately after calling ModalDialog, SFGetFile calls you dlgHook
function, passing it the item number returned by ModalDialog and a
pointer to the dialog record describing you dialog box. Using these
two parameters, your dlgHook function should determine how to handle
the event. There are predefined constants for the item numbers of
standard enabled items, as follows:

    CONST getOpen    = 1;   {Open button}
          getCancel  = 3;   {Cancel button}
      getEject   = 5;   {Eject button}
      getDrive   = 6;   {Drive button}
      getNmList  = 7;   {userItem for file name list}
      getScroll  = 8;   {userItem for scroll bar}

    ModalDIalog also returns "fake" item numbers in the following
situations, which are detected by its filterProc function:

   - When a disk-inserted event occurs, it returns 100.

   - When a key-down event occurs, it returns 1000 plus the ASCII code
     of the character.

    After handling the event (or, perhaps, after ignoring it) your
dlgHook function must return an item number to SFGetFile. If the item
number is one of those listed above, SFGetFile responds in the standard
way; otherwise, it does nothing.
\ SFPGetFile
13
PROCEDURE SFPGetFile (where: Point; prompt: Str255; fileFilter:
            ProcPtr; numTypes: INTEGER; typeList: SFTypeList; dlgHook:
        ProcPtr; VAR reply: SFReply; dlgID: INTEGER; filterProc:
        ProcPtr);

    SFPGetFile is an alternative to SFGetFile for advanced programmers
who want to use a nonstandard dialog box. It's the same as  SFGetFile
except for the two additional parameters dlgID and filterProc.

    DlgID is the rexource ID of the dialog template to be used instead
of the standard one (so you can use whatever ID you wish rather than the
smae one as the standard).

    The filterProc parameter determines how ModalDialog will filter
events when called by SFPGetFile. If filterProc is NIL, ModalDialog
does the standard filtering that it does when called by SFGetFile;
otherwise, filterProc should point to a function for ModalDialog to
execute after doing the standard filtering. Note, however, that the
standard filtering will detect key-down events only if the dialog
template ID is the standard one.
\ DILoad
13
PROCEDURE DILoad;

    DILoad reads the Disk Initialization Package, and its associated
dialog and dialog items, from the system resource file into memory and
makes them unpurgeaable.

(note)
       DIFormat, DIVerify, and DIZero don't need the dialog, so
       if you use only these routines you can call the Resource
       Manager function GetResource to read just the package
       resource into memory (and the Memory Manager procedure
       HNoPurge to make it unpurgeable).
\ DIUnload
13
PROCEDURE DIUnload;

    DIUnload makes the Disk Initialization Package (and its associated
dialog an dialog items) purgeable.
\ DIBadMount
13
FUNCTION DIBadMount (where: Point; evtMessage: LongInt) : INTEGER;

    Call DIBadMount when a disk-inserted event occurs if the result code
in the high-order word of the associated event message indicates an
error (that is, the result code is other than noErr). Given the event
message in evtMessage, DIBadMount evaluates the result code and either
ejects the disk or lets the user initialize and name it. The low-order
word of the event message contains the drive number. The where
parameter specifies the location (in global coordinates) of the top
left corner of the dialog box displayed by DIBadMount.

    If the result code passed is extFSErr, mFulErr, nsDrvErr, paramErr
, or volOnLinErr, DIBadMount displays a dialog box that describes the
problem and asks whether the user wants to initialized the disk. For
the result code ioErr, the dialog box shown in Figure D-1 is displayed.
(This happens if the disk is brand new.)  For badMDBErr and noMacDskErr,
DIBadMount displays a similar dialog box in which the description of
the problem is "This disk is damaged" and "This is not a Macintosh
disk", respectively.

(note)
       Before presenting the disk initialization dialog,
       DIBadMount checks whether the drive contains an already
       mounted volume; if so, it ejects the disk and returns 2
       as its result. This will happen rarely and may reflect
       an error in your program (for example, you forgot to call
       DILoad and the user had to switch to the disk containing
       the system resource file).

    If the user responds to the disk initialization dialog by clicking
the Eject button, DIBadMount ejects the disk and returns 1 as its result
If the Initialize button is clicked, a box displaying the message
"Initializing disk..." appears, and DIBadMount attempts to initialize
the disk. If initialization fails, the disk is ejected and the user is
informed as shown in Figure D-2; after the user clicks OK, DIBadMount
returns a negative result code ranging from firstDskErr to lastDskErr,
indicating that a low-level disk error occurred.

    If the disk is successfully initialized, the dialog box in Figure D
appears. After the user names the disk and clicks OK, DIBadMount
mounts the volume by calling the File Manager function PBMountVol and
returns PBMountVol's result code (noErr if no error occurs).

      Result codes
      ------------
      noErr                No error
      extFSErr             External file system
      mFulErr              Memory full
      nsDrvErr             No such drive
      paramErr             Bad drive number
      volOnLinErr          Volume already on-line
      firstDskErr          Low-level disk error
      through lastDskErr

      Other results
      -------------
      1                    User clicked Eject
      2                    Mounted volume in drive
\ DIFormat
13
FUNCTION DIFormat (drvNum: INTEGER) : OSErr;

    DILFormat formats the disk in the drive specified by the given drive
number and returns a result code indicating whether the formatting was
completed successfully or failed. Formatting a disk consists of
writing special infromation onto it so that the Disk Driver can read
from and write to the disk.

      Result codes
      ------------
      noErr               No error
      firstDskErr         Low-level disk error
\ DIVerify
13
FUNCTION DIVerify (drvNum: INTEGER) : OSErr;

    DIVerify verifies the format of the disk in the drive specified by
the given drive number; it reads each bit from the disk and returns a
result code indicating whether all bits were read successfully or not.

      Result codes
      ------------
      noErr                 No error
      firstDskErr           Low-level disk error
\ DIZero
13
FUNCTION DIZero (drvNum: INTEGER; volName: Str255) : OSErr;

    On the unmounted volume in the drive specified by the given drive
number, DIZero writes the volume information, a block map, and a file
directory as for a volume with no files; the volName parameter
specifies the volume name to be included in the volume information.
This is the last step in initialization (after formatting and
verifying) and makes any files that are already on the volume
permanently inaccessible. If the operation fails, DIZero returns a
result code indicating that a low-level disk error occurred; otherwise,
it mounts the volume by calling the File Manager function PBMountVol
and returns PBMountVol's result code (noEr if no error occurs).


      Result codes
      ------------
      noErr                    No error
      badMDBErr                Bad master directory block
      extFSErr                 External file system
      ioErr                    Disk I/O error
      mFulErr                  Memory full
      noMacDskErr              Not a Macintosh volume
      nsDrvErr                 No such drive
      paramErr                 Bad drive number
      volOnLinErr              Volume already on-line
      firstDskErr              Low-level disk error
      through lastDskErr
\ InitApplZone
14
PROCEDURE InitApplZone;

      _________________________________________________________

      Trap macro            _InitApplZone
      On exit               D0:  result code (integer)

      _________________________________________________________


    InitApplZone initializes the application heap zone and makes it the
current zone. The contents of any previous application zone are lost;
all previously existing blocks in that zone are discarded.
InitApplZone is called by the Segment Loader when starting up an
application;  you shouldn't normally need to call it.

(warning)
       Reinitializing the application zone from within a running
       program is tricky, since the program's code itself
       resides in the application zone. To do it safely, the
       code containing the InitApplZone call cannot be in the
       application zone.

    The application zone has an initial size of 6K bytes, and can be
expanded as needed in 1K increments. Space is initially allocated for
64 master pointers; should more be needed later, they will be added 64
at a time. The zone's grow zone function is set to NIL.

       Result codes        noErr         No eror
\ SetApplBase
14
PROCEDURE SetApplBase (startPtr: Ptr);

            _________________________________________________

     Trap macro               _SetApplBase
     On entry                 A0:  startPtr (pointer)
     On exit                  D0:  result code (integer)

            _________________________________________________


    SetApplBase changes the starting address of the application heap
zone to the address designated by startPtr, and then calls IniApplZone.
SetApplBase is normally called only by the system itself; you should
never need to call this procedure.

    Since the application heap zone begins immediately folowing the end
of the system zone, changingits starting address has the effect of
changing the size of the system zone. The system zone can be made
larger, but never smaller; if startPtr points to an address lower than
the current end of the system zone, it's ignored and the application
zone's starting address is left unchanged.

(warning)
      Like InitApplZone, SetApplBase is a tricky operation,
      because the code of the program itself resides in the
      application heap zone. To do it safely, the code
      containing the SetApplBase call cannot be in the
      application zone.

      Result codes     noErr             No error
\ InitZone
14
PROCEDURE InitZone (pGrowZone: ProcPtr; cMoreMasters: INTEGER;
                    limitPtr, startPtr: Ptr);


       ________________________________________________________

        Trap macro            _InitZone

        On entry              A0:  pointer to parameter block

        Parameter block
               0      startPtr       pointer
               4      limitPtr       pointer
               8      cMoreMasters   integer
              10      pGrowZone      pointer

        On exit                D0: result code (integer)

       ________________________________________________________


    InitZone creates a new heap zone initializes its header and trailer,
and makes it the current zone. The startPtr parameter is a pointer to
the first byte of the new zone; limitPtr points to the first byte of
the zone trailer. The new zone will occupy memory addresses from
ORD(startPtr) to ORD(limitPtr)+11.

    CMoreMasters tells how many master pointers should be allocated at a
time for the new zone. This number of master pointers are created
initially; should more be needed later, they will be added in
increments of this same number. For the system heap zone, this number
is initially 32; for the application heap zone, it's 64.

    The pGrowZone parameter is a pointer to the grow zone function for
the new zone, if any. If you're not defining a grow zone function for
this zone, pass NIL.

    The new zone includes a 52-byte header, so its actual usable space
runs from ORD(startPtr)+52 through ORD(limitPtr)-1. In addition, each
master pointer occupies four bytes within this usable area. Thus the
total available space in the zone, in bytes, is initially

      ORD(limitPtr) - ORD(startPtr) - 52 - 4*cMoreMasters

    This number must not be less than 0. Note that the amount of
available space in the zone will decrease as more master pointers are
allocated.

      Result codes        noErr                No error
\ SetApplLimit
14
PROCEDURE SetApplLimit (zoneLimit: Ptr);

        _________________________________________________

         Trap macro        _SetApplLimit

         On entry          A0:  zoneLimit (pointer)

         On exit           D0:  result code (integer)

        _________________________________________________


    SetApplLimit sets the application heap limit, beyond which the
application heap zone can't be expanded. The actual expansion isn't
under your program's control, but is done automatically by the Memory
Manager when necessary to satisfy allocation requests. Only the
original application zone can be expanded.

    ZoneLimit  is a limit pointer to a byte in memory beyond which the
zone will not be allowed to grow. The zone can grow to include the byte
preceding zoneLimit in memory, but no farther. If the zone already
extends beyond the specified limit it won't be cut back, but it will be
prevented from growing any more.

(warning)
       Notice that zoneLimit is not a byte count. To limit the
       application zone to a particular size (say 8Kbytes), you
       have to write something like

            SetApplLimit(Ptr(ApplicZone)+8192)

       The Memory Manager function ApplicZone is explained
       below.


            _________________________________________________

       Assembly-language note:  The global variable ApplLimit contains
       the application heap limit.

            _________________________________________________


       Result codes      noErr           No error
\ MaxApplZone
14
PROCEDURE MaxApplZone;    [No trap macro]

    MaxApplZone expands the application heap zone to the application
heap limit without purging any blocks currently in the zone. If the
zone already extends to the limit, it won't be changed.

      Result codes      noErr           No error
\ MoreMasters
14
PROCEDURE MoreMasters;

            _________________________________________________

       Trap macro         _MoreMasters

            _________________________________________________

    MoreMasters allocates another block of master pointers in the
current heap zone. This procedure is usually called very early in an
application.

     Result codes
     ------------
     noErr             No error
     memFullErr        Not enough room in zone
\ GetZone
14
FUNCTION GetZone:  THz;

            _________________________________________________

      Trap macro             _GetZone

      On exit                A0:  function result (pointer)
                             D0:  result code (integer)
            _________________________________________________

    GetZone returns a pointer to the curent heap zone.

            _________________________________________________

      Assembly-language note:  The global variable TheZone contains a
      pointer to the current heap zone.
            _________________________________________________

      Result codes      noErr          No error
\ SetZone
14
PROCEDURE SetZone (hz: THz);

            _________________________________________________

       Trap macro      _SetZone

       On entry        A0:  hz (pointer)

       On exit         D0:  result code (integer)
            _________________________________________________

    SetZone sets the current heap zone to the zone pointed to by hz.

            _________________________________________________

       Assembly-language note:  You can set the current heap zone by
       storing a pointer to it in the global variable TheZone.
            _________________________________________________

       Result codes          noErr           No error



\ SystemZone
14
FUNCTION SystemZone : THz;       [No trap macro]

    SystemZone returns a pointer to the system heap zone.

            _________________________________________________

       Assembly-language note:  The global variable SysZone contains a
       pointer to the system heap zone.
            _________________________________________________

       Result codes            noErr        No error
\ ApplicZone
14
PROCEDURE ApplicZone : THz;  [No trap macro]

    ApplicZone returns a pointer to the original application heap zone.

            _________________________________________________

     Assembly-language note:  The global variable ApplZone contains a
     pointer to the original application heap zone.
            _________________________________________________

     Result codes         noErr          No error
\ NewHandle
14
FUNCTION NewHandle (logicalSize: Size) : Handle;

    __________________________________________________________

Trap macro       _NewHandle
                 _NewHandle ,SYS           (applies to system heap)
                 _NewHandle ,CLEAR         (clears allocated block)
                 _NewHandle ,SYS,CLEAR     (applies to system heap and
                                            clears allocated block)

On entry         D0:  logicalSize (long integer)

On exit          A0:  function result (handle)
                 D0:  result code (integer)
    __________________________________________________________

    NewHandle attempts to allocate a new relocatable block of
logicalSize bytes from the current heap zone and then return a handle to
it. The new block will be unlocked and unpurgeable. If logicalSize bytes
can't be allocated, NewHandle returns NIL.

    NewHandle will pursue all available avenues to create a free block
of the requested size, includinig compacting the heap zone, increasing
its size, purging blocks from it, and calling its grow zone function, if
any.

       Result codes     noErr           No error
                        memFulErr       Not enough room in zone
\ DisposHandle
14
PROCEDURE DisposHandle (h: Handle);

            _________________________________________________

      Trap macro           _DisposHandle

      On entry             A0:  h (handle

      On exit              A0:  0
                           D0: result code (integer)
            _________________________________________________

    DisposHandle releases the memory occupied by the relocatable block
whose handle is h.

(warning)
       After a call to DisposHandle, all handles to the released
       block become invalid and should not be used again.

       Result codes     noErr       No error
                        memWZErr    Attempt to operate on a free block
\ GetHandleSize
14
FUNCTION GetHandleSize (h: Handle) : Size;

            _________________________________________________

     Trap macro      _GetHandleSize

     On entry        A0:  h (handle)

     On exit         D0:  if >=0, function result (long integer)
                          if <0, result code (integer)
            _________________________________________________

    GetHandleSize returns the logical size, in bytes, of the relocatable
block whose handle is h. In case of an error, GetHandleSize returns 0.

            _________________________________________________

     Assembly-language note:  Recall that the trap dispatcher sets
     the condition codes before returning from a trap by testing the
     low-order word of register D0 with a TST.W instruction. Since
     the block size returned in D0 by _GetHandleSize is a full 32-bit
     long word, the word-length test sets the condition codes
     incorrectly in this case. To branch on the contents of D0, use
     your own TST.L instruction on return from the trap to test the
     full 32 bits of the register.
            _________________________________________________

     Result codes    noErr           No error   [Pascal only]
                    nilHandleErr     NIL master pointer
                    memWZErr         Attempt to operate on a free block
\ SetHandleSize
14
PROCEDURE SetHandleSize (h: Handle; newSize: Size);

            _________________________________________________

     Trap macro          _SetHandleSize

     On entry       A0:  h (handle)
                    D0:  newSize (long integer)

     On exit        D0:  result code (integer)
            _________________________________________________

    SetHandleSize changes the logical size of the relocatable block
whose handle is h to newSize bytes.

(note)
       Don't attempt to increase the size of a locked block,
       becausse its unlikely the Memory Manager will be able to
       do so.

       Result codes

       noErr         No error
       memFullErr    Not enough room to grow
       nilHandleErr  NIL master pointer
       memWZErr      Attempt to operate on a free block
\ HandleZone
14
FUNCTION HandleZone (h: Handle) : THz;

        _________________________________________________

          Trap macro    _HandleZone

          On entry      A0: h (handle)

          On exit       A0:  function result (pointer)
                        D0:  result code (integer)
        _________________________________________________

    HandleZone returns a pointer to the heap zone containing the
relocatable block whose handle is h.

(warning)
        If handle h is empty (points to a NIL master pointer),
    HandleZone returns a pointer to the current heap zone.
    In case of an error, the result returned by HandleZone is
    meaningless and should be ignored.

Result codes      noErr            No error
                  memWZErr         Attempt to operate on a free block
\ RecoverHandle
14
FUNCTION RecoverHandle (p:Ptr) : Handle;

            _________________________________________________

      Trap macro      _RecoverHandle
                      _RecoverHandle ,SYS     (applies to system heap)

      On entry        A0:  p (pointer)

      On exit         A0:  function result (handle)
                      D0:  unchanged
            _________________________________________________


    RecoverHandle returns a handle to the relocataable block pointed to
by p.

            _________________________________________________

    Assembly-language note:  The trap _RecoverHandle doesn't return
    a result code in register D0; the previous contents of D0 are
    preserved unchanged.
            _________________________________________________

    Result codes     noErr          No error   [Pascal only]
\ ReallocHandle
14
PROCEDURE ReallocHandle (h: Handle; logicalSize: Size);

            _________________________________________________

    Trap macro         _ReallocHandle

    On entry           A0:  h (handle)
                       D0:  logicalSize   (integer)

    On exit            A0:  original h or 0
                       D0:  result code  (integer)
            _________________________________________________

    ReallocHandle allocates a new relocatable block with a logical size
of logicalSize bytes. It then updates handle h by setting its master
pointer to point to the new block. The main use of this procedure is
to reallocate space for a block that has been purged. Normally h is an
empty handle, but it need not be:  if it points to an existing block,
that block is released before the new block is created.

    In case of an error, no new block is allocated and handle h is left
unchanged.

            _________________________________________________

    Assembly-language note:  On return from ReallocHandle, register
    A0 contains the original handle h, or 0 if no room could be
    found for the requested block.
            _________________________________________________

    Result codes

            noErr       Noerror
            memFullErr  Not enough room in zone
            memWZErr    Attempt to operate on a free block
            MemPurErr   Block is locked
\ NewPtr
14
FUNCTION NewPtr (logicalSize: Size) : Ptr;

            _________________________________________________

    Trap macro  _NewPtr
                _NewPtr ,SYS        (applies to system heap)
                _NewPtr ,CLEAR      (clears allocated block)
                _NewPtr ,SYS,CLEAR  (applies to system heap and
                                    clears allocated block)

    On entry    D0:  logicalSize (long integer)

    On exit     A0:  function result (pointer)
                D0:  result code (integer)
            _________________________________________________

    NewPtr attempts to allocate a new nonrelocatable block of
logicalSize bytes from the current heap zone and then return a pointer
to it. If logicalSize bytes can't be allocated, NewPtr returns NIL.

    Newptr will pursue all available avenues to create a free block of
the requested size, including compacting the heap zone, increasing its
size, purging blocks from it, and calling its grow zone function, if
any.

    Result codes

            noErr       No error
            memFullErr  Not enough room in zone
\ DisposPtr
14
PROCEDURE DisposPtr (p: Ptr);

          _________________________________________________

            Trap macro  _DisposPtr

            On entry    A0:  p (pointer)

            On exit     A0:  0
                        D0:  result code (integer)
          _________________________________________________

    DisposPtr releases the memory occupied by the nonrelocatable block
pointed to by p.

(warning)
    After a call to DisposPtr, all pointers to the released
    block become invalid and should not be used again.

    Result codes

            noErr       No error
            memWZErr    Attempt to operated on a free block
\ GetPtrSize
14
FUNCTION GetPtrSize (p: Ptr) : Size;

    ___________________________________________________________

    Trap macro  _GetPtrSize

    On entry    A0:  p (pointer)

    On exit     D0:  if >=0, function result (long integer)
                     if <0, result code (integer)
    ___________________________________________________________

    GetPtrSize returns the logical size, in bytes, of the nonrelocatable
block pointed to by p. In case of an error, GetPtrSize returns 0.

    ___________________________________________________________

    Assembly-language note:  Recall that the trap dispatcher sets
    the condition codes before returning from a trap by testing the
    low-order half of register D0 with a TST.W instruction. Since
    the block size returned in D0 by _GetPtrSize is a full 32-bit
    long word, the word-length test sets the condition codes
    incorrectly in this case. To branch on the contents of D0, use
    your own TST.L instruction on return from the trap to test the
    full 32 bits of the register.
    ___________________________________________________________

    Result codes

            noErr       No error   [Pascal only]
            memWZErr    Attempt to operate on a free block
\ SetPtrSize
14
PROCEDURE SetPtrSize (p: Ptr; newSize: Size);

    ___________________________________________________________

    Trap macro  _SetPtrSize

    On entry    A0:  p (pointer)

    On exit     A0:  function result (pointer)
            D0:  result code (integer)
    ___________________________________________________________

    PtrZone returns a pointer to the heap zone containing the
nonrelocatable block pointed to by p. In case of an error, the result
returned by PtrZone is meaningless and should be ignored.

    Result codes

            noErr       No error
            memWZErr    Attempt to operate on a free block
\ FreeMem
14
FUNCTION FreeMem : LONGINT;

        _______________________________________________________

        Trap macro  _FreeMem
                    _FreeMem ,SYS   (applies to system heap

        On exit     D0:  function result (long integer)
        _______________________________________________________

    FreeMem returns the total amount of free space in the current heap
zone, in bytes. Notice that it ususally isn't possible to allocate a 
block of this size, because of fragmentation due to nonrelocatable or
locked blocks.

    Result codes

            noErr   No error
\ MaxMem
14
FUNCTION MaxMem (VAR grow: Size) : Size;

            _________________________________________________

    Trap macro  _MaxMem
                _MaxMem ,SYS            (applies to system heap)

    On exit     D0:  function result    (long integer)
                A0:  grow               (long integer)
            _________________________________________________

    MaxMem compacts the current heap zone and purges all purgeable
blocks from the zone. It returns as its result the size in bytes of the
largest contiguous free block in the zone after the compaction. If the
current zone is the original application heap zone, the variable
parameter grow is set to the maximum number of bytes by which the zone
can grow. For any other heap zone, grow is set to 0. MaxMem doesn't
actually expand the zone or call its grow zone function.

    Result codes

            noErr   No error
\ CompactMem
14
FUNCTION CompactMem (cbNeeded: Size) : Size;

    ___________________________________________________________

    Trap macro  _CompactMem
                _CompactMem ,SYS    (applies to system heap)

    On entry    D0:  cbNeeded (longinteger)

    On exit     D0:  function result (long integer)
    ___________________________________________________________

    CompactMem compacts the current heap zone by moving relocatable
blocks forward and collecting free space together until a contiguous
block of at least cbNeeded free bytes is found or the entire zone is
compacted; it doesn't purge any purgeable blocks. CompactMem returns
the size in bytes of the largest contiguous free block remaining. Note
that it doesn't actually allocate the block.

(notee)
    To force a compaction of the entire heap zone, pass
    maxSize for cbNeeded.

    Result codes

        noErr       No error
\ ResrvMem
14
FUNCTION ResrvMem (cbNeeded: Size);

    ___________________________________________________________

    Trap macro  _ResrvMem
                _ResrvMem ,SYS      (applies to system heap)

    On entry    D0:  cbNeeded (long integer)

    On exit     D0:  result code  (integer)
    ___________________________________________________________

    ResrvMem creates free space for a block of cbNeeded contiguous bytes
at the lowest possible position in the current heap zone. It will try
every available means to place the block as close as possible to the
beginnig of the zone, including moving other blocks upward, expanding
the zone, or purging blocks from it. Notice that ResrvMem doesn't
actually allocate the block.

(note)
    When you allocate a relocatable block that you know will
    be locked for long periods of time, call ResrvMem first.
    This reserves space for the block near the beginning of
    the heap zone, where it will interfere with compaction as
    little as possible. It isn't necessary to call ResrvMem
    for a nonrelocatable block; NewPtr calls it
    automatically.

    Result codes

            noErr       No error
            memFullErr  Not enough room in zone
\ PurgeMem
14
PROCEDURE PurgeMem (cbNeeded: Size);

    ___________________________________________________________

    Trap macro  _PurgeMem
                _PurgeMEM ,SYS  (applies to system heap)

    On entry    D0:  cbNeeded (long integer)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    PurgeMem sequentially purges blocks from the current heap zone until
a contiguous block of at least cbNeeded free bytes is created or the
entire zone is purged; it doesn't compact the heap zone. Only
relocatable, unlocked, purgeable blocks can be purged. Notice that
PurgeMem doesn't actually allocate the block.

(note)
    To force a purge of the entire heap zone, pass maxSize
    for cbNeeded.

    Result codes

            noErr       No error
            memFullErr  Not enough room in zone
\ EmptyHandle
14
PROCEDURE EmptyHandle (h: Handle);

    ___________________________________________________________

    TRap macro  _EmptyHandle

    On entry    A0:  h (handle)

    On exit     A0:  h (handle)
                D0:  result code (integer)
    ___________________________________________________________

    EmptyHandle purges the relocatable block whose handle is h from its
heap zone and sets its master pointer to NIL (making it an empty
handle). If h is already empty, EmptyHandle does nothing.

(note)
    Since the space occupied by the block's master pointer
    itself remains allocated, all handles pointing to it
    remain valid but empty. When you later reallocate space
    for the block with ReallocHandle, the master pointer will
    be updated, causing all existing handles to point
    correctly to the new block.

    The block whose handle is h must be unlocked, but need not be
purgeable.

    Result codes

            noErr       No error
            memWZErr    Attempt to operate on a free block
            memPurErr   Block is locked
\ HLock
14
PROCEDURE HLock (h: Handle);

    ___________________________________________________________

    Trap macro  _HLock

    On entry    A0:  h (handle)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    HLock locks a relocatable block, preventing it from being moved
within its heap zone. If the block is already locked, HLock does
nothing.

    ___________________________________________________________

    Assembly-language note:  Changing the value of the block's
    master pointer's lock bit with a BSET instruction is faster than
    HLock. However, HLock may eventually perform additional tasks.
    ___________________________________________________________

    Result codes

            noErr       No error
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to opetate on a free block
\ HUnlock
14
PROCEDURE HUnlock (h: Handle);

    ___________________________________________________________

    Trap macro  _HUnlock

    On entry    A0:  h (handle)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    HUnlock unlocks a relocatable block, allowing it to be moved within
its heap zone. If the block is already unlocked, HUnlock does nothing.

    ___________________________________________________________

    Assembly-language note:  Changing the value of the block's
    master pointer's lock bit with a BCLR instruction is faster than
    HUnlock. However, HUnlock may eventually perform additional
    tasks.
    ___________________________________________________________

    Result codes

            noErr           No error
            nilHandleErr    NIL master pointer
            memWZErr        Attempt to operate on a fre block
\ HPurge
14
PROCEDURE HPurge (h: Handle);

    ___________________________________________________________

    Trap macro  _HPurge

    On entry    A0:  h (handle)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    HPurge marks a relocatable block as purgeable. If the block is
already purgeable, HPurge does nothing.

    Result codes

            noErr       No error
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to operate on a free block
\ HNoPurge
14
PROCEDURE HNoPurge (h: Handle);

    ___________________________________________________________
    Trap macro  _HNoPurge

    On entry    A0:  h (handle)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    HNoPurge marks a relocatable block as unpurgeable. If the block is
already unprugeable, HNoPurge does nothing.

    Result codes

            noErr           No error
            nilHandleErr    NIL master pointerr
            memWZErr        Attempt to operate on a free block
\ SetGrowZone
14
PROCEDURE SetGrowZone (growZone: ProcPtr);

    ___________________________________________________________

    Trap macro  _SetGrowZone

    On entry    A0:  growZone (pointer)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    SetGrowZone sets the current heap fzone's grow zone function as
designated by the growZone parameter. A NIL parameter value removes
any grow zone function the zone may previously have had.

(note)
    If yokur program presses the limits of the available heap
    space, it's a good idea to have a grow zone function of
    some sort. At the very least, the grow zone function
    should detect when the Memory Manager is about to run out
    of space at a critical time (see GZCritical, below) and
    take some graceful action--such as displaying an alert
    box with the message "Out of memory"--instead of just
    failing unpredictably.

    The Memory Manager calls the grow zone function as a last resort
when trying to allocate space, if it has failed to create a block of the
needed size after compacting the zone, increasing its size (in the case
of the origianal application zone), or purging blocks from it. Memory
Manager routines that may cause the grow zone function to be called are
NewHandle, NewPtr, SetHandleSize, SetPtrSize, ReallocHandle, and
ResrvMem.

The grow zone function should be of the form

    FUNCTION MyGrowZone (cbNeeded: Size) : Size;

    The cbNeeded parameter gives the physical size of the needed block
in bytes, including the block header. The grow zone function should
attempt to create a free block of at least this size. It should return
a nonzero number if it's abale to allocate some memory, or 0 if it's not
able to allocate any.

    If the grow zone function returns 0, the Memory Manager will give up
trying to allocate the needed block and will signal failure with the
result code memFullErr. Otherwise it will compact the heap zone and
try again to allocate the block. If still unsuccessful, it will
continue to call the grow zone function repeatedly, compacting the zone
again after each call, until it either succeeds in allocating the
needed block or receives a zero result and gives up.

    The usual way for the grow zone function to free more space is to
call EmptyHandle to purge blocks that were previously marked
unpurgeable. Another possibility is to unlock blocks that were
previously locked.

(note)
    Although just unlocking blocks doesn't actually free any
    additional space in the zone, the grow zone function
    should still return a nonzero result in this case. This
    signals the Memory Manager to compact the heap and try
    again to allocate the needed block.

(warning)
    Depending on the circumstances in which the grow zone
    function is called, there may be particular blocks within
    the heap zone that must not be purged or released. For
    instance, if your program is attempting to increase the
    size of a relocatable block with SetHandleSize, it would
    be disastrous to release the block being expanded. To
    deal with such cases safely, it's essential to understand
    the use of the functions GZCritical and GZSaveHnd (see
    below).

(warning)
    Whenever you call the Resource Manager with
    SetResPurge(TRUE), it installs its own grow zone function
    into the application heap zone. The Resource Manager's
    grow zone function automatically writes to the disk all
    changed resources before they're purged. If you install
    your own grow zone function into the application heap
    zone, you shouldn't call SetResPurge(TRUE).

    Result codes

            noErr   No error
\ GZCritical
14
FUNCTION GZCritical : BOOLEAN;    [No trap macro]

    GZCritical retruns TRUE if the Memory Manager critically needs
space-- for example, to create a new relocatable or nonrelocatable block
or to reallocate a handle. It returns FALSE in less critical cases,
such as ResrvMem trying to reserve space as low as possible in the heap
zone or SetHandleSize trying to increase the size of a relocatable
block. GZCritical doesn't affect the value returned by MemError.

(warning)
    If you're writing a grow zone function in Pascal, you
    should always call GZCritical and proceed only if the
    result is TRUE. All the information you need to handle
    the critical cases safely is the value of GZSaveHnd (see
    below). The noncritical cases require additional
    information that isn't available from Pascal, so your
    grow zone function should just return 0 and not attempt
    to free any space.
\ GZSaveHnd
14
FUNCTION GZSaveHnd : Handle;   [No trap macro]

    GZSave Hnd retruns a handle to a relocatable block that mustn't be
purged or released by the grow zone function, or NIL if there is no
such block. For example, during a SetHandleSize call, the handle being
changed mustn't be purged. The grow zone function will be safe if it
avoids purging or releasing this block, provided that the grow zone
call was critical. To handle noncritical cases safely, further
information is needed that isn't available from Pascal. GZSaveHnd
doesn't affect the value returned by MemError.
\ BlockMove
14
PROCEDURE BlockMove (sourcePtr,destPtr: Ptr; byteCount: Size);


    ___________________________________________________________

    Trap macro  _BlockMove

    On entry    A0:  sourcePtr (pointer)
                A1:  destPtr (pointer)
                D0:  byteCount (long integer)

    On exit     D0:  result code (integer)
    ___________________________________________________________

    BlockMove moves a block of byteCount consecutive bytes from the
address designated by sourcePtr to that designated by destPtr. No
pointers are updated.

    Result codes

            noErr   No error
\ TopMem
14
FUNCTION TopMem : Ptr;   [No trap macro]

    TopMem returns a pointer to the address following the last byte of
RAM.

            _________________________________________________

    Assembly-language note:  To get a pointer to the end of RAM from
    assembly language, use the global variable MemTop.
            _________________________________________________

    Result codes

            noErr   No error
\ MemError
14
FUNCTION MemError : OSErr;   [No trap macro]

    MemError returns the result code produced by the last Memory Manager
routine called. (OSErr is an Operating System Utility data type
declared as INTEGER.)
\MaxBlock
14
FUNCTION MaxBlock : LONGINT;
    ______________________________________________________________

    Trap macro  _MaxBlock
                _MaxBlock ,SYS  (applies to system heap)

    On exit     D0:  function result (word)
    ______________________________________________________________
    MaxBlock returns the maximum contiguous space in bytes that could be
obtained by compacting the current zone (without actually doing
the compaction).
\PurgeSpace
14
PROCEDURE PurgeSpace (VAR total,contig: LONGINT);
    ______________________________________________________________

    Trap macro  _PurgeSpace
                _PurgeSpace ,SYS    (applies to system heap)

    On exit     A0:  contig (long word)
                D0:  total (long word)
    ______________________________________________________________
    PurgeSpace returns in total the total amount of space in bytes that
could be obtained by a general purge (without actually doing
the purge); this amount includes space that is already free.
The maximum contiguous space in bytes (including already free space)
that could be obtained by a purge is returned in contig.
\StackSpace
14
FUNCTION StackSpace : LONGINT;
    ______________________________________________________________

    Trap macro  _StackSpace

    On exit     D0:  function result (word)
    ______________________________________________________________
    StackSpace returns the current amount of stack space between the
current stack pointer and the application heap (at the instant
of return from the trap).
\NewEmptyHandle
14
FUNCTION NewEmptyHandle : Handle;
    ______________________________________________________________

    Trap macro  _NewEmptyHandle
                _NewEmptyHandle ,SYS    (applies to system heap)

    On exit     A0:  function result (handle)
                D0:  result code (word)
    ______________________________________________________________

    NewEmptyHandle is similar in function to NewHandle except that it
does not allocate any space; the handle returned is empty (in
other words, it points to a NIL master pointer). NewEmptyHandle
is used extensively by the Resource Manager; you may not need to use it.
\HSetRBit
14
PROCEDURE HSetRBit (h: Handle);
    ______________________________________________________________

    Trap macro  _HSetRBit

    On entry    A0:  h (handle)

    On exit     D0:  result code (word)
    ______________________________________________________________

    HSetRBit sets the resource flag of a relocatable blockÕs master
pointer.
\HClrRBit
14
PROCEDURE HClrRBit (h: Handle);
    ______________________________________________________________

    Trap macro  _HClrRBit

    On entry    A0:  h (handle)

    On exit     D0:  result code (word)
    ______________________________________________________________
    HClrRBit clears the resource flag of a relocatable blockÕs master
pointer.
\HGetState
14
FUNCTION HGetState (h: Handle) : SignedByte;
    ______________________________________________________________

    Trap macro  _HGetState

    On entry    A0:  h (handle)

    On exit     D0:  flags (byte)
    ______________________________________________________________
    HGetState returns the byte that contains the flags of the master
pointer for the given handle; itÕs used in conjunction with HSetState
to save and restore the state of the flags contained in this byte.
You can save this byte, change the state of any of the flags (using
the routines described above), and then restore their original state
by passing the byte back to the HSetState procedure (described below).
\HSetState
14
PROCEDURE HSetState (h: Handle; flags: SignedByte);
    ______________________________________________________________

    Trap macro  _HSetState

    On entry    A0:  h (handle)
                D0:  flags (byte)

    On exit     D0:  result code (word)
    ______________________________________________________________

    HSetState is used in conjunction with HGetState; it sets the byte
that contains the flags of the master pointer for the given handle
to the byte specified by flags.
\ UnloadSeg
15
PROCEDURE UnloadSeg (routineAddr: Ptr);

    UnloadSeg unloads a segment, making it relocatable and purgeable;
routineAddr is the address of any externally referenced routine in the
segment. The segment won't actually be purged until the memory it
occupies is needed. If the segment is purged, the Segment Loader will
reload it the next time one of the routines in it is called.
\ CountAppFiles
15
PROCEDURE COuntAppFiles (VAR message:  INTEGER; VAR count: INTEGER);

    CountAppFiles deciphers the Finder information passed to your
application, and returns information about the documents that were
selected when your application was started up. It returns the number
of selected documents in the count parameter, and a number in the
message parameter that indicates whether the documents are to be opened
or printed:

    CONST appOpen  = 0;   {open the document(s)}
          appPrint = 1;   {print the document(s)}
\ GetAppFiles
15
PROCEDURE GetAppFiles (index: INTEGER; VAR theFile: AppFile);

    GetAppFiles returns information about a document that was selected
when your application was started up (as listed in the Finder
information). The index parameter indicates the file for which
information should be returned; it must be between 1 and the number
returned by CountAppFiles, inclusive. The information is returned in
the following data structure:

    TYPE AppFile = RECORD
            vRefNum: INTEGER;  {volume reference number}
            fType:   OSType;   {file type}
            versNum: INTEGER;  {version number}
            fName:   Str255;   {file name}
          END;

    Volume reference number, file type, version number, and file name
are discussed in the File Manager manual.
\ ClrAppFiles
15
PROCEDURE ClrAppFiles (index: INTEGER);

    ClrAppFiles changes the Finder information passed to your aplication
about the specified file such that the Finder knows you've processed
the file. The index parameter must be between 1 and the number
returned by CountAppFiles, inclusive. You should call ClrAppFiles for
every document your application opens or prints, so that the
information returned by CountAppFiles and GetAppFiles is always
correct. (ClrAppFiles sets the file type in the Finder information to
0.)
\ GetAppParms
15
PROCEDURE GetAppParms (VAR apName: STRING[31]; VAR apRefNum: INTEGER;
        VAR apParam: Handle);

    GetAppParms returns information about the current application. It
returns the application name in apName and the reference number for the
application's resource file in apRefNum. A handle to the Finder
information is returned in apParam, but the Finder information is more
easily accessed with the GetAppFiles call.
\ ExitToShell
15
PROCEDURE ExitToShell;

    ExitToShell provides an exit from an application by starting up the
Finder (after releasing the entire application heap).
\ GetOSEvent
16
FUNCTION GetOSEvent (eventMask: INTEGER; VAR theEvent: EventRecord) :
                        BOOLEAN;

    ____________________________________________________________

    Trap macro  _GetOSEvent

    On entry    A0:  pointer to event record theEvent
                D0:  eventMask (word)

    On exit     D0:  0 if non-null event returned, or
                 -1 if null event returned (byte)
    ____________________________________________________________

    GEtOSEvent returns the next available event of a specified type or
types and removes it from the event queue. The event is returned as
the value of the parameter theEvent. The eventMask parameter specifies
which event types are of interest. GetOSEvent will return the next
available event of any type designated by the mask. If no event of any
of the designated types is available, GetOSEvent returns a null event
and a function result of FALSE; otherwise it returns TRUE.
\ OSEventAvail
16
FUNCTION OSEventAvail (eventMask: INTEGER; VAR theEvent: EventRecord) :
                        BOOLEAN;

    __________________________________________________________________

    Trap macro  _OSEventAvail

    On entry    A0:  pointer to event record theEvent
                D0:  eventMask (word)

    On exit     D0:  0 if not-null event returned, or
                    -1 if null event returned (byte)
    __________________________________________________________________

    OSEventAvail works exactly the same as GetOSEvent (above) except
that it doesn't remove the event from the event queue.

(note)
    An event returned by OSEventAvail will not be accessible
    later if in the meantime the queue becomes full and the
    event is discarded from it; since the events discarded
    are always the oldest ones in the queue, however, this
    will happen only in an unusually busy environment.
\ SetEventMask
16
PROCEDURE SetEventMask (theMask: INTEGER);  [No trap macro]

    SetEventMask sets the system event mask to the specified event mask.
The Operating System Event Manager will post only those event types
that correspond to bits set in the mask. (As usual, it will not post
activate and update events, which are generated by the Window Manager
and not stored in the event queue.)  The system event mask is initially
set to post all except key-up events.

(warning)
    Because desk accessories may rely on receiving certain
    types of events, your application shouldn't set the
    system event mask to prevent any additional types
    (besides key-up) from being posted. You should use
    SetEventMask only to enable key-up events in the unusual
    case that your application needs to respond to them.
\ GetEvQHdr
16
FUNCTION GetEvQHdr : QHdrPtr;  [No trap macro]

    GetEvQHdr retruns a pointer to the event queue.
\ PPostEvent
16
FUNCTION PPostEvent (eventCode: INTEGER; eventMsg: LONGINT;
                        VAR qEl: EvQEl) : OSErr);
    ____________________________________________________________

        Trap macro  _PPostEvent

        On entry    A0:  eventCode (word)
                    D0:  eventMsg (long word)

        On exit     A0:  pointer to event queue entry
    ____________________________________________________________
    PPostEvent is identical to PostEvent except that it returns a
pointer to the created queue entry.
\ GetVInfo
17
FUNCTION GetVInfo (drvNum: INTEGER; volName: StringPtr;
                  VAR vRefNum: INTEGER; VAR freeBytes: LONGINT)
                  : OSErr;  [Not in ROM]

    GetVInfo returns the name, reference number, and available space
(in bytes), in volName, vRefNum, and freeBytes, for the volume in
the drive specified by drvNum.

Result codes    noErr     No error
                nsvErr    No default volume
                paramErr  Bad drive number
\ GetVRefNum
17
FUNCTION GetVRefNum (pathRefNum: INTEGER; VAR vRefNum: INTEGER)
                    : OSErr;  [Not in ROM]

    Given a path reference number in pathRefNum, GetVRefNum returns
the volume reference number in vRefNum.

Result codes    noErr       No error
                rfNumErr    Bad reference number
\ GetVol
17
FUNCTION GetVol (volName: StringPtr; VAR vRefNum: INTEGER)
                : OSErr;  [Not in ROM]

    GetVol returns the name of the default volume in volName and its
volume reference number in vRefNum.

Result codes    noErr   No error
                nsvErr  No such volume
\ SetVol
17
FUNCTION SetVol (volName: StringPtr; vRefNum: INTEGER)
                : OSErr;  [Not in ROM]

    SetVol sets the default volume to the mounted volume specified
by volName or vRefNum.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                nsvErr      No such volume
                paramErr    No default volume
\ FlushVol
17
FUNCTION FlushVol (volName: StringPtr; vRefNum: INTEGER)
                    : OSErr;  [Not in ROM]

    On the volume specified by volName or vRefNum, FlushVol writes
the contents of the associated volume buffer and descriptive
information about the volume (if theyÕve changed since the last
time FlushVol was called).

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ UnmountVol
17
FUNCTION UnmountVol (volName: StringPtr; vRefNum: INTEGER)
                    : OSErr;  [Not in ROM]

    UnmountVol unmounts the volume specified by volName or vRefNum,
by calling FlushVol to flush the volume buffer, closing all
open files on the volume, and releasing the memory used for the volume.

Warning:  DonÕt unmount the startup volume.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ Eject
17
FUNCTION Eject (volName: StringPtr; vRefNum: INTEGER)
                : OSErr;  [Not in ROM]

    Eject flushes the volume specified by volName or vRefNum,
places it off-line, and then ejects the volume.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ Create
17
FUNCTION Create (fileName: Str255; vRefNum: INTEGER; creator: OSType;
                fileType: OSType) : OSErr;  [Not in ROM]

    Create creates a new file (both forks) with the specified name,
file type, and creator on the specified volume. (File type and
creator are discussed in the Finder Interface chapter.)
The new file is unlocked and empty. The date and time of its
creation and last modification are set to the current date and time.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dupFNErr    Duplicate file name and version
                dirFulErr   File directory full
                extFSErr    External file system
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ FSOpen
17
FUNCTION FSOpen (fileName: Str255; vRefNum: INTEGER; VAR refNum: INTEGER)
                : OSErr;  [Not in ROM]

    FSOpen creates an access path to the file having the name fileName
on the volume specified by vRefNum. A path reference number is returned
in refNum. The access pathÕs read/write permission is set to whatever
the fileÕs open permission allows.

Note:  ThereÕs no guarantee that any bytes have been written until
       FlushVol is called.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                tmfoErr     Too many files open
\ FSRead
17
FUNCTION FSRead (refNum: INTEGER; VAR count: LONGINT; buffPtr: Ptr)
                : OSErr;  [Not in ROM]

    FSRead attempts to read the number of bytes specified by the count
parameter from the open file whose access path is specified by
refNum, and transfer them to the data buffer pointed to by buffPtr.
The read operation begins at the current mark, so you might want to
precede this with a call to SetFPos. If you try to read past the
logical end-of-file, FSRead moves the mark to the end-of-file and
returns eofErr as its function result. After the read is completed,
the number of bytes actually read is returned in the count parameter.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative count
                rfNumErr    Bad reference number
\ FSWrite
17
FUNCTION FSWrite (refNum: INTEGER; VAR count: LONGINT; buffPtr: Ptr)
                    : OSErr;  [Not in ROM]

    FSWrite takes the number of bytes specified by the count parameter
from the buffer pointed to by buffPtr and attempts to write them to
the open file whose access path is specified by refNum. The write
operation begins at the current mark, so you might want to precede
this with a call to SetFPos. After the write is completed, the number
of bytes actually written is returned in the count parameter.

Result codes    noErr       No error
                dskFulErr   Disk full
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative count
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ GetFPos
17
FUNCTION GetFPos (refNum: INTEGER; VAR filePos: LONGINT)
                : OSErr;  [Not in ROM]

    GetFPos returns, in filePos, the mark of the open file whose access
path is specified by refNum.

Result codes    noErr       No error
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
\ SetFPos
17
FUNCTION SetFPos (refNum: INTEGER; posMode: INTEGER; posOff: LONGINT)
                    : OSErr;  [Not in ROM]

    SetFPos sets the mark of the open file whose access path is
specified by refNum to the position specified by posMode and posOff
(except when posMode is equal to fsAtMark, in which case posOff is
ignored). PosMode indicates how to position the mark; it must contain
one of the following values:

CONST fsAtMark    = 0;  {at current mark}
      fsFromStart = 1;  {set mark relative to beginning of file}
      fsFromLEOF  = 2;  {set mark relative to logical end-of-file}
      fsFromMark  = 3;  {set mark relative to current mark}

    If you specify fsAtMark, posOffset is ignored and the mark is left
wherever itÕs currently positioned. If you choose to set the mark
(relative to either the beginning of the file, the logical end-of-file,
or the current mark), posOffset specifies the byte offset from the
chosen point (either positive or negative) where the mark should be set.
If you try to set the mark past the logical end-of-file, SetFPos moves
the mark to the end-of-file and returns eofErr as its function result.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                posErr      Attempt to position before start of file
                rfNumErr    Bad reference number

\ GEtEOF
17
FUNCTION GetEOF (refNum: INTEGER; VAR logEOF: LONGINT)
                : OSErr;  [Not in ROM]

    GetEOF returns, in logEOF, the logical end-of-file of the open
file whose access path is specified by refNum.

Result codes    noErr       No error
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
\ SetEOF
17
FUNCTION SetEOF (refNum: INTEGER; logEOF: LONGINT)
                : OSErr;  [Not in ROM]

    SetEOF sets the logical end-of-file of the open file whose access
path is specified by refNum to the position specified by logEOF.
If you attempt to set the logical end-of-file beyond the physical
end-of-file, the physical end-of-file is set to one byte beyond
the end of the next free allocation block; if there isnÕt enough
space on the volume, no change is made, and SetEOF returns dskFulErr
as its function result. If logEOF is 0, all space occupied by the file
on the volume is released.

Result codes    noErr       No error
                dskFulErr   Disk full
                extFSErr    External file system
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ Allocate
17
FUNCTION Allocate (refNum: INTEGER; VAR count: LONGINT)
                    : OSErr;  [Not in ROM]

    Allocate adds the number of bytes specified by the count parameter
to the open file whose access path is specified by refNum, and sets the
physical end-of-file to one byte beyond the last block allocated.
The number of bytes actually allocated is rounded up to the nearest
multiple of the allocation block size, and returned in the count
parameter. If there isnÕt enough empty space on the volume to satisfy
the allocation request, Allocate allocates the rest of the space on the
volume and returns dskFulErr as its function result.

Result codes    noErr       No error
                dskFulErr   Disk full
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ FSClose
17
FUNCTION FSClose (refNum: INTEGER) : OSErr;  [Not in ROM]

    FSClose removes the access path specified by refNum, writes the
contents of the volume buffer to the volume, and updates the fileÕs
entry in the file directory.

Note:  ThereÕs no guarantee that any bytes have been written until
       FlushVol is called.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                fnOpnErr    File not open
                ioErr       I/O error
                nsvErr      No such volume
                rfNumErr    Bad reference number
\ GetFInfo
17
FUNCTION GetFInfo (fileName: Str255; vRefNum: INTEGER; VAR
                    fndrInfo: FInfo) : OSErr;  [Not in ROM]

    For the file having the name fileName on the specified volume,
GetFInfo returns information used by the Finder in fndrInfo
(see the section ŌFile Information Used by the FinderĶ).

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
\ SetFInfo
17
FUNCTION SetFInfo (fileName: Str255; vRefNum: INTEGER;
                    fndrInfo: FInfo) : OSErr;  [Not in ROM]

    For the file having the name fileName on the specified volume,
SetFInfo sets information used by the Finder to fndrInfo (see
the section ŌFile Information Used by the FinderĶ).

Result codes    noErr       No error
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ SetFLock
17
FUNCTION SetFLock (fileName: Str255; vRefNum: INTEGER)
                : OSErr;  [Not in ROM]

    SetFLock locks the file having the name fileName on the specified
volume. Access paths currently in use arenÕt affected.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ RstFLock
17
FUNCTION RstFLock (fileName: Str255; vRefNum: INTEGER)
                    : OSErr;  [Not in ROM]

    RstFLock unlocks the file having the name fileName on the specified
volume. Access paths currently in use arenÕt affected.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ Rename
17
FUNCTION Rename (oldName: Str255; vRefNum: INTEGER; newName: Str255)
                : OSErr;  [Not in ROM]

    Given a file name in oldName, Rename changes the name of the file to
newName. Access paths currently in use arenÕt affected. Given a volume
name in oldName or a volume reference number in vRefNum, Rename changes
the name of the specified volume to newName.

Warning:  If youÕre renaming a volume, be sure that both names end with
          a colon.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirFulErr   Directory full
                dupFNErr    Duplicate file name
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                fsRnErr     Problem during rename
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ FSDelete
17
FUNCTION FSDelete (fileName: Str255; vRefNum: INTEGER)
                    : OSErr;  [Not in ROM]

    FSDelete removes the closed file having the name fileName from the
specified volume.

Note:  This function will delete both forks of a file.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fBsyErr     File busy
                fLckdErr    File locked
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ OpenRF
17
FUNCTION OpenRF (fileName: Str255; vRefNum: INTEGER;
                VAR refNum: INTEGER) : OSErr;  [Not in ROM]

    OpenRF is similar to FSOpen; the only difference is that OpenRF
opens the resource fork of the specified file rather than the data fork.
A path reference number is returned in refNum. The access pathÕs
read/write permission is set to whatever the fileÕs open permission
allows.

Note:  Normally you should access a fileÕs resource fork through the
       routines of the Resource Manager rather than the File Manager.
       OpenRF doesnÕt read the resource map into memory; itÕs really
       only useful for block-level operations such as copying files.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                tmfoErr     Too many files open
\ FInitQueue
17
PROCEDURE InitQueue;

Trap macro  _InitQueue

FInitQueue clears all queued File Manager calls except the current one.
\ PBMountVol
17
FUNCTION PBMountVol (paramBlock: ParmBlkPtr) : OSErr;

Trap macro  _MountVol

Parameter block
    <Ņ  16  ioResult    word
    <Đ> 22  ioVRefNum   word

    PBMountVol mounts the volume in the drive specified by ioVRefNum,
and returns a volume reference number in ioVRefNum. If there are no
volumes already mounted, this volume becomes the default volume.
PBMountVol is always executed synchronously.

Note:  When mounting hierarchical volumes, PBMountVol opens two files
       needed for maintaining file directory and file mapping
       information. PBMountVol can fail if there are no access paths
       available for these two files; it will return tmfoErr as its
       function result.

Result codes    noErr       No error
                badMDBErr   Bad master directory block
                extFSErr    External file system
                ioErr       I/O error
                memFullErr  Not enough room in heap zone
                noMacDskErr Not a Macintosh disk
                nsDrvErr    No such drive
                paramErr    Bad drive number
                tmfoErr     Too many files open
                volOnLinErr Volume already on-line
\ PBGetVInfo
17
FUNCTION PBGetVInfo (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetVolInfo

Parameter block
    Ņ>  12      ioCompletion    pointer
    <Ņ  16      ioResult        word
    <Đ> 18      ioNamePtr       pointer
    <Đ> 22      ioVRefNum       word
    Ņ>  28      ioVolIndex      word
    <Ņ  30      ioVCrDate       long word
    <Ņ  34      ioVLsBkUp       long word
    <Ņ  38      ioVAtrb         word
    <Ņ  40      ioVNmFls        word
    <Ņ  42      ioVDirSt        word
    <Ņ  44      ioVBlLn         word
    <Ņ  46      ioVNmAlBlks     word
    <Ņ  48      ioVAlBlkSiz     long word
    <Ņ  52      ioVClpSiz       long word
    <Ņ  56      ioAlBlSt        word
    <Ņ  58      ioVNxtFNum      long word
    <Ņ  62      ioVFrBlk        word

    PBGetVInfo returns information about the specified volume. If
ioVolIndex is positive, the File Manager attempts to use it to find the
volume; for instance, if ioVolIndex is 2, the File Manager will attempt
to access the second mounted volume. If ioVolIndex is negative, the
File Manager uses ioNamePtr and ioVRefNum in the standard way (described
in the section ŌSpecifying Volumes, Directories, and FilesĶ) to
determine which volume. If ioVolIndex is 0, the File Manager attempts
to access the volume by using ioVRefNum only. The volume reference
number is returned in ioVRefNum, and a pointer to the volume name is
returned in ioNamePtr (unless ioNamePtr is NIL).

    If a working directory reference number is passed in ioVRefNum (or
if the default directory is a subdirectory), the number of files and
directories in the specified directory (the directoryÕs valence) will be
returned in ioVNmFls. Also, the volume reference number wonÕt be
returned; ioVRefNum will still contain the working directory reference
number.

Warning:  IOVNmAlBlks and ioVFrBlks, which are actually unsigned
          integers, are clipped to 31744 ($7C00) regardless of the size
          of the volume.

Result codes    noErr       No error
                nsvErr      No such volume
                paramErr    No default volume
\ PBHGetVInfo
17
FUNCTION PBHGetVInfo (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HGetVInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer
    <Đ> 22  ioVRefNum       word
    Ņ>  28  ioVolIndex      word
    <Ņ  30  ioVCrDate       long word
    <Ņ  34  ioVLsMod        long word
    <Ņ  38  ioVAtrb         word
    <Ņ  40  ioVNmFls        word
    <Ņ  42  ioVBitMap       word
    <Ņ  44  ioVAllocPtr     word
    <Ņ  46  ioVNmAlBlks     word
    <Ņ  48  ioVAlBlkSiz     long word
    <Ņ  52  ioVClpSiz       long word
    <Ņ  56  ioAlBlSt        word
    <Ņ  58  ioVNxtFNum      long word
    <Ņ  62  ioVFrBlk        word
    <Ņ  64  ioVSigWord      word
    <Ņ  66  ioVDrvInfo      word
    <Ņ  68  ioVDRefNum      word
    <Ņ  70  ioVFSID         word
    <Ņ  72  ioVBkUp         long word
    <Ņ  76  ioVSeqNum       word
    <Ņ  78  ioVWrCnt        long word
    <Ņ  82  ioVFilCnt       long word
    <Ņ  86  ioVDirCnt       long word
    <Ņ  90  ioVFndrInfo     32 bytes

    PBHGetVInfo is similar in function to PBGetVInfo but returns a
larger parameter block. In addition, PBHGetVInfo always returns the
volume reference number in ioVRefNum (regardless of what was passed in).
Also, ioVNmAlBlks and ioVFrBlks are not clipped as they are by
PBGetVInfo.

Result codes    noErr       No error
                nsvErr      No such volume
                paramErr    No default volume
\ PBSetVInfo
17
FUNCTION PBSetVInfo (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetVolInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  30  ioVCrDate       long word
    Ņ>  34  ioVLsMod        long word
    Ņ>  38  ioVAtrb         word
    Ņ>  52  ioVClpSiz       long word
    Ņ>  72  ioVBkUp         long word
    Ņ>  76  ioVSeqNum       word
    Ņ>  90  ioVFndrInfo     32 bytes

    PBSetVInfo lets you modify information about volumes. A pointer to
a new name for the volume can be specified in ioNamePtr. The date and
time of the volumeÕs creation and modification can be set with ioVCrDate
and ioVLsMod respectively. Only bit 15 of ioVAtrb can be changed;
setting it locks the volume.

Note: The volume cannot be specified by name; you must use either the
       volume reference number or the drive number.

Warning:  PBSetVInfo operates only with the hierarchical version of the
          File Manager; if used on a Macintosh equipped only with the
          64K ROM version of the File Manager, it will generate a system
          error.

Result codes    noErr       No error
                nsvErr      No such volume
                paramErr    No default volume
\ PBGetVol
17
FUNCTION PBGetVol (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetVol

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Ņ  18  ioNamePtr       pointer
    <Ņ  22  ioVRefNum       word

    PBGetVol returns a pointer to the name of the default volume in
ioNamePtr (unless ioNamePtr is NIL) and its volume reference number in
ioVRefNum. If a default directory was set with a previous PBSetVol
call, a pointer to its name will be returned in ioNamePtr and its
working directory reference number in ioVRefNum.

Result codes    noErr   No error
                nsvErr  No default volume
\ PBHGetVol
17
FUNCTION PBHGetVol (paramBlock: WDPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _HGetVol

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Ņ  18  ioNamePtr       pointer
    <Ņ  22  ioVRefNum       word
    <Ņ  28  ioWDProcID      long word
    <Ņ  32  ioWDVRefNum     word
    <Ņ  48  ioWDDirID       long word

    PBHGetVol returns the default volume and directory last set by
either a PBSetVol or a PBHSetVol call. The reference number of the
default volume is returned in ioVRefNum.

Warning:  IOVRefNum will return a working directory reference number
          (instead of the volume reference number) if, in the last call
          to PBSetVol or PBHSetVol, a working directory reference number
          was passed in this field.

    The volume reference number of the volume on which the default
directory exists is returned in ioWDVRefNum. The directory ID of the
default directory is returned in ioWDDirID.

Result codes    noErr   No error
                nsvErr  No default volume
\ PBSetVol
17
FUNCTION PBSetVol (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetVol

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word

    PBSetVol sets the default volume to the mounted volume specified by
ioNamePtr or ioVRefNum. On hierarchical volumes, PBSetVol also sets the
root directory as the default directory.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                nsvErr      No such volume
                paramErr    No default volume
\ PBHSetVol
17
FUNCTION PBHSetVol (paramBlock: WDPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _HSetVol

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  48  ioWDDirID       long word

    PBHSetVol sets both the default volume and the default directory.
The default directory to be used can be specified by either a volume
reference number or a working directory reference number in ioVRefNum, a
directory ID in ioWDDirID, or a pointer to a pathname (possibly NIL) in
ioNamePtr.

Note:  Both the default volume and  the default directory are used in
       calls made with no volume name and a volume reference number of
       zero.

Result codes    noErr   No error
                nsvErr  No default volume
\ PBFlushVol
17
FUNCTION PBFlushVol (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _FlushVol

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word

    On the volume specified by ioNamePtr or ioVRefNum, PBFlushVol writes
descriptive information about the volume, the contents of the associated
volume buffer, and all access path buffers for the volume (if theyÕve
changed since the last time PBFlushVol was called).

Note:  The date and time of the last modification to the volume are set
       when the modification is made, not when the volume is flushed.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ PBUnmountVol
17
FUNCTION PBUnmountVol (paramBlock: ParmBlkPtr) : OSErr;

Trap macro  _UnmountVol

Parameter block
    <Ņ  16  ioResult    word
    Ņ>  18  ioNamePtr   pointer
    Ņ>  22  ioVRefNum   word

    PBUnmountVol unmounts the volume specified by ioNamePtr or
ioVRefNum, by calling PBFlushVol to flush the volume, closing all open
files on the volume, and releasing the memory used for the volume.
PBUnmountVol is always executed synchronously.

Warning:  DonÕt unmount the startup volume.

Note:  Unmounting a volume does not close working directories; to
       release the memory allocated to a working directory, call
       PBCloseWD.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ PBOffLine
17
FUNCTION PBOffLine (paramBlock: ParmBlkPtr) : OSErr;

Trap macro  _OffLine

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult    word
    Ņ>  18  ioNamePtr   pointer
    Ņ>  22  ioVRefNum   word

    PBOffLine places off-line the volume specified by ioNamePtr or
ioVRefNum, by calling PBFlushVol to flush the volume and releasing all
the memory used for the volume except for the volume control block.
PBOffLine is always executed synchronously.

Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ PBEject
17
FUNCTION PBEject (paramBlock: ParmBlkPtr) : OSErr;

Trap macro  _Eject

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word

    PBEject flushes the volume specified by ioNamePtr or ioVRefNum,
places it off-line, and then ejects the volume.
________________________________________________________________________

Assembly-language note:  You may invoke the macro _Eject asynchronously;
the first part of the call is executed synchronously, and the actual
ejection is executed asynchronously.
________________________________________________________________________
Result codes    noErr       No error
                bdNamErr    Bad volume name
                extFSErr    External file system
                ioErr       I/O error
                nsDrvErr    No such drive
                nsvErr      No such volume
                paramErr    No default volume
\ PBOpen
17
FUNCTION PBOpen (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Open

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioRefNum        word
    Ņ>  26  ioVersNum       byte
    Ņ>  27  ioPermssn       byte
    Ņ>  28  ioMisc          pointer

    PBOpen creates an access path to the file having the name pointed to
by ioNamePtr (and on flat volumes, the version number ioVersNum) on the
volume specified by ioVRefNum. A path reference number is returned in
ioRefNum.

    IOMisc either points to a portion of memory (522 bytes) to be used
as the access pathÕs buffer, or is NIL if you want the volume buffer to
be used instead.

Warning:  All access paths to a single file thatÕs opened multiple times
          should share the same buffer so that they will read and write
          the same data.

    IOPermssn specifies the pathÕs read/write permission. A path can be
opened for writing even if it accesses a file on a locked volume, and an
error wonÕt be returned until a PBWrite, PBSetEOF, or PBAllocate call is
made.

    If you attempt to open a locked file for writing, PBOpen will return
permErr as its function result. If you request exclusive read/write
permission but another access path already has write permission (whether
write only, exclusive read/write, or shared read/write), PBOpen will
return the reference number of the existing access path in ioRefNum and
opWrErr as its function result. Similarly, if you request shared
read/write permission but another access path already has exclusive
read/write permission, PBOpen will return the reference number of the
access path in ioRefNum and opWrErr as its function result.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                permErr     Attempt to open locked file for writing
                tmfoErr     Too many files open
\ PBHOpen
17
FUNCTION PBHOpen (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HOpen

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioRefNum        word
    Ņ>  27  ioPermssn       byte
    Ņ>  28  ioMisc          pointer
    Ņ>  48  ioDirID         long word

    PBHOpen is identical to PBOpen except that it accepts a directory ID
in ioDirID.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                permErr     Attempt to open locked file for writing
                tmfoErr     Too many files open

\ PBOpenRF
17
FUNCTION PBOpenRF (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _OpenRF

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioRefNum        word
    Ņ>  26  ioVersNum       byte
    Ņ>  27  ioPermssn       byte
    Ņ>  28  ioMisc          pointer

    PBOpenRF is identical to PBOpen, except that it opens the fileÕs
resource fork instead of its data fork.

Note:  Normally you should access a fileÕs resource fork through the
       routines of the Resource Manager rather than the File Manager.
       PBOpenRF doesnÕt read the resource map into memory; itÕs really
       only useful for block-level operations such as copying files.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                permErr     Attempt to open locked file for writing
                tmfoErr     Too many files open
\ PBHOpenRF
17
FUNCTION PBHOpenRF (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HOpenRF

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioRefNum        word
    Ņ>  27  ioPermssn       byte
    Ņ>  28  ioMisc          pointer
    Ņ>  48  ioDirID         long word

    PBHOpenRF is identical to PBOpenRF except that it accepts a
directory ID in ioDirID.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                opWrErr     File already open for writing
                permErr     Attempt to open locked file for writing
                tmfoErr     Too many files open
\ PBLockRange
17
FUNCTION PBLockRange (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _LockRng

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  36  ioReqCount      long word
    Ņ>  44  ioPosMode       word
    Ņ>  46  ioPosOffset     long word

    On a file opened with a shared read/write permission, PBLockRange is
used in conjunction with PBRead and PBWrite to lock a certain portion of
the file. PBLockRange uses the same parameters as both PBRead and
PBWrite; by calling it immediately before PBRead, you can use the
information present in the parameter block for the PBRead call.

    When youÕre finished with the data (typically after a call to
PBWrite), be sure to call PBUnlockRange to free up that portion of the
file for subsequent PBRead calls.

Warning:  PBLockRange operates only with the hierarchical version of the
          File Manager; if used on a Macintosh equipped only with the
          64K ROM version of the File Manager, it will generate a system
          error.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative ioReqCount
                rfNumErr    Bad reference number
\ PBUnlockRange
17
FUNCTION PBUnlockRange (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _UnlockRng

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  36  ioReqCount      long word
    Ņ>  44  ioPosMode       word
    Ņ>  46  ioPosOffset     long word

    PBUnlockRange is used in conjunction with PBRead and PBWrite to
unlock a certain portion of a file that you locked with PBLockRange.
PBUnlockRange uses the same parameters as both PBRead and PBWrite; by
calling it immediately after PBWrite, you can use the information
present in the parameter block to unlock the portion of the file that
was just written.

Warning:  PBUnlockRange operates only with the hierarchical version of
          the File Manager; if used on a Macintosh equipped only with
          the 64K ROM version of the File Manager, it will generate a
          system error.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative ioReqCount
                rfNumErr    Bad reference number
\ PBRead
17
FUNCTION PBRead (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Read

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  32  ioBuffer        pointer
    Ņ>  36  ioReqCount      long word
    <Ņ  40  ioActCount      long word
    Ņ>  44  ioPosMode       word
    <Đ> 46  ioPosOffset     long word

    PBRead attempts to read ioReqCount bytes from the open file whose
access path is specified by ioRefNum, and transfer them to the data
buffer pointed to by ioBuffer. The position of the mark is specified by
ioPosMode and ioPosOffset. If you try to read past the logical
end-of-file, PBRead moves the mark to the end-of-file and returns eofErr
as its function result. After the read is completed, the mark is
returned in ioPosOffset and the number of bytes actually read is
returned in ioActCount.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative ioReqCount
                rfNumErr    Bad reference number
\ PBWrite
17
FUNCTION PBWrite (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Write

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  32  ioBuffer        pointer
    Ņ>  36  ioReqCount      long word
    <Ņ  40  ioActCount      long word
    Ņ>  44  ioPosMode       word
    <Đ> 46  ioPosOffset     long word

    PBWrite takes ioReqCount bytes from the buffer pointed to by
ioBuffer and attempts to write them to the open file whose access path
is specified by ioRefNum. The position of the mark is specified by
ioPosMode and ioPosOffset. After the write is completed, the mark is
returned in ioPosOffset and the number of bytes actually written is
returned in ioActCount.

Result codes    noErr       No error
                dskFulErr   Disk full
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                paramErr    Negative ioReqCount
                posErr      Attempt to position before start of file
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ PBGetFPos
17
FUNCTION PBGetFPos (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetFPos

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    <Ņ  36  ioReqCount      long word
    <Ņ  40  ioActCount      long word
    <Ņ  44  ioPosMode       word
    <Ņ  46  ioPosOffset     long word

    PBGetFPos returns, in ioPosOffset, the mark of the open file whose
access path is specified by ioRefNum. It sets ioReqCount, ioActCount,
and ioPosMode to 0.

Result codes    noErr       No error
                extFSErr    External file system
                fnOpnErr    File not open
                gfpErr      Error during GetFPos
                ioErr       I/O error
                rfNumErr    Bad reference number
\ PBSetFPos
17
FUNCTION PBSetFPos (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetFPos

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  44  ioPosMode       word
    <Đ> 46  ioPosOffset     long word

    PBSetFPos sets the mark of the open file whose access path is
specified by ioRefNum to the position specified by ioPosMode and
ioPosOffset. The position at which the mark is actually set is returned
in ioPosOffset. If you try to set the mark past the logical
end-of-file, PBSetFPos moves the mark to the end-of-file and returns
eofErr as its function result.

Result codes    noErr       No error
                eofErr      End-of-file
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                posErr      Attempt to position before start of file
                rfNumErr    Bad reference number
\ PBGetEOF
17
FUNCTION PBGetEOF (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetEOF

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    <Ņ  28  ioMisc          long word

    PBGetEOF returns, in ioMisc, the logical end-of-file of the open
file whose access path is specified by ioRefNum.

Result codes    noErr       No error
                extFSErr    External file system
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
\ PBSetEOF
17
FUNCTION PBSetEOF (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetEOF

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  28  ioMisc          long word

    PBSetEOF sets the logical end-of-file of the open file, whose access
path is specified by ioRefNum, to ioMisc. If you attempt to set the
logical end-of-file beyond the physical end-of-file, another allocation
block is added to the file; if there isnÕt enough space on the volume,
no change is made, and PBSetEOF returns dskFulErr as its function
result. If ioMisc is 0, all space occupied by the file on the volume is
released.

Result codes    noErr       No error
                dskFulErr   Disk full
                extFSErr    External file system
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ PBAllocate
17
FUNCTION PBAllocate (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Allocate

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  36  ioReqCount      long word
    <Ņ  40  ioActCount      long word

    PBAllocate adds ioReqCount bytes to the open file whose access path
is specified by ioRefNum, and sets the physical end-of-file to one byte
beyond the last block allocated. The number of bytes actually allocated
is rounded up to the nearest multiple of the allocation block size, and
returned in ioActCount. If there isnÕt enough empty space on the volume
to satisfy the allocation request, PBAllocate allocates the rest of the
space on the volume and returns dskFulErr as its function result.

Note:  Even if the total number of requested bytes is unavailable,
       PBAllocate will allocate whatever space, contiguous or not, is
       available. To force the allocation of the entire requested space
       as a contiguous piece, call PBAllocContig instead.

Result codes    noErr       No error
                dskFulErr   Disk full
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ PBAllocContig
17
FUNCTION PBAllocContig (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _AllocContig

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word
    Ņ>  36  ioReqCount      long word
    <Ņ  40  ioActCount      long word

    PBAllocContig is identical to PBAllocate except that if there isnÕt
enough contiguous empty space on the volume to satisfy the allocation
request, PBAllocContig will do nothing and will return dskFulErr as its
function result. If you want to allocate whatever space is available,
even when the entire request cannot be filled as a contiguous piece,
call PBAllocate instead.

Result codes    noErr       No error
                dskFulErr   Disk full
                fLckdErr    File locked
                fnOpnErr    File not open
                ioErr       I/O error
                rfNumErr    Bad reference number
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
                wrPermErr   Read/write permission doesnÕt allow writing
\ PBFlushFile
17
FUNCTION PBFlushFile (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _FlushFile

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word

    PBFlushFile writes the contents of the access path buffer indicated
by ioRefNum to the volume, and updates the fileÕs entry in the file
directory (or in the file catalog, in the case of hierarchical volumes).

Warning:  Some information stored on the volume wonÕt be correct until
          PBFlushVol is called.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                fnOpnErr    File not open
                ioErr       I/O error
                nsvErr      No such volume
                rfNumErr    Bad reference number

\ PBClose
17
FUNCTION PBClose (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Close

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  24  ioRefNum        word

    PBClose writes the contents of the access path buffer specified by
ioRefNum to the volume and removes the access path.

Warning:  Some information stored on the volume wonÕt be correct until
          PBFlushVol is called.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                fnOpnErr    File not open
                ioErr       I/O error
                nsvErr      No such volume
                rfNumErr    Bad reference number

\ PBCreate
17
FUNCTION PBCreate (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Create

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioFVersNum      byte

    PBCreate creates a new file (both forks) having the name pointed to
by ioNamePtr (and on flat volumes, the version number ioVersNum) on the
volume specified by ioVRefNum. The new file is unlocked and empty. The
date and time of its creation and last modification are set to the
current date and time. If the file created isnÕt temporary (that is, if
it will exist after the application terminates), the application should
call PBSetFInfo (after PBCreate) to fill in the information needed by
the Finder.
________________________________________________________________________

Assembly-language note:  If a desk accessory creates a file, it should
always create it in the directory containing the system folder. The
working directory reference number for this directory is stored in the
global variable BootDrive; you can pass it in ioVRefNum.
________________________________________________________________________

Result codes    noErr       No error
                bdNamErr    Bad file name
                dupFNErr    Duplicate file name and version
                dirFulErr   File directory full
                extFSErr    External file system
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBHCreate
17
FUNCTION PBHCreate (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HCreate

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  48  ioDirID         long word

    PBHCreate is identical to PBCreate except that it accepts a
directory ID in ioDirID.

Note:  To create a directory instead of a file, call PBDirCreate.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dupFNErr    Duplicate file name and version
                dirFulErr   File directory full
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBDirCreate
17
FUNCTION PBDirCreate (paramBlock: HParmBlkPtr; async: BOOLEAN): OSErr;

Trap macro  _DirCreate

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Đ> 48  ioDirID         long word

    PBDirCreate is identical to PBHCreate except that it creates a new
directory instead of a file. You can specify the parent of the
directory to be created in ioDirID; if itÕs 0, the new directory will be
placed in the root directory. The directory ID of the new directory is
returned in ioDirID.

Warning:  PBDirCreate operates only with the hierarchical version of the
          File Manager; if used on a Macintosh equipped only with the
          64K ROM version of the File Manager, it will generate a system
          error.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dupFNErr    Duplicate file name and version
                dirFulErr   File directory full
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock

\ PBDelete
17
FUNCTION PBDelete (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Delete

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioFVersNum      byte

    PBDelete removes the closed file having the name pointed to by
ioNamePtr (and on flat volumes, the version number ioVersNum) from the
volume pointed to by ioVRefNum. PBHDelete can be used to delete an
empty directory as well.

Note:  This function will delete both forks of the file.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fBsyErr     File busy, directory not empty, or working
                            directory control block open
                fLckdErr    File locked
                fnfErr      File not found
                nsvErr      No such volume
                ioErr       I/O error
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBHDelete
17
FUNCTION PBHDelete (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HDelete

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  48  ioDirID         long word

    PBHDelete is identical to PBDelete except that it accepts a
directory ID in ioDirID. PBHDelete can be used to delete an empty
directory as well.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fBsyErr     File busy, directory not empty,
                            or working directory control block open
                fLckdErr    File locked
                fnfErr      File not found
                nsvErr      No such volume
                ioErr       I/O error
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBGetFInfo
17
FUNCTION PBGetFInfo (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetFileInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioFRefNum       word
    Ņ>  26  ioFVersNum      byte
    Ņ>  28  ioFDirIndex     word
    <Ņ  30  ioFlAttrib      byte
    <Ņ  31  ioFlVersNum     byte
    <Ņ  32  ioFlFndrInfo    16 bytes
    <Ņ  48  ioFlNum         long word
    <Ņ  52  ioFlStBlk       word
    <Ņ  54  ioFlLgLen       long word
    <Ņ  58  ioFlPyLen       long word
    <Ņ  62  ioFlRStBlk      word
    <Ņ  64  ioFlRLgLen      long word
    <Ņ  68  ioFlRPyLen      long word
    <Ņ  72  ioFlCrDat       long word
    <Ņ  76  ioFlMdDat       long word

    PBGetFInfo returns information about the specified file. If
ioFDirIndex is positive, the File Manager returns information about the
file whose directory index is ioFDirIndex on the volume specified by
ioVRefNum. (See the section ŌData Organization on VolumesĶ if youÕre
interested in using this method.)

Note:  If a working directory reference number is specified in
       ioVRefNum, the File Manager returns information about the file
       whose directory index is ioFDirIndex in the specified directory.

    If ioFDirIndex is negative or 0, the File Manager returns
information about the file having the name pointed to by ioNamePtr (and
on flat volumes, the version number ioFVersNum) on the volume specified
by ioVRefNum. If the file is open, the reference number of the first
access path found is returned in ioFRefNum, and the name of the file is
returned in ioNamePtr (unless ioNamePtr is NIL).

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
\ PBHGetFInfo
17
FUNCTION PBHGetFInfo (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HGetFileInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioFRefNum       word
    Ņ>  28  ioFDirIndex     word
    <Ņ  30  ioFlAttrib      byte
    <Ņ  32  ioFlFndrInfo    16 bytes
    <Đ> 48  ioDirID         long word
    <Ņ  52  ioFlStBlk       word
    <Ņ  54  ioFlLgLen       long word
    <Ņ  58  ioFlPyLen       long word
    <Ņ  62  ioFlRStBlk      word
    <Ņ  64  ioFlRLgLen      long word
    <Ņ  68  ioFlRPyLen      long word
    <Ņ  72  ioFlCrDat       long word
    <Ņ  76  ioFlMdDat       long word

    PBHGetFInfo is identical to PBGetFInfo except that it accepts a
directory ID in ioDirID.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
\ PBSetFInfo
17
FUNCTION PBSetFInfo (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetFileInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioFVersNum      byte
    Ņ>  32  ioFlFndrInfo    16 bytes
    Ņ>  72  ioFlCrDat       long word
    Ņ>  76  ioFlMdDat       long word

    PBSetFInfo sets information (including the date and time of creation
and modification, and information needed by the Finder) about the file
having the name pointed to by ioNamePtr (and on flat volumes, the
version number ioFVersNum) on the volume specified by ioVRefNum. You
should call PBGetFInfo just before PBSetFInfo, so the current
information is present in the parameter block.

Result codes    noErr       No error
                bdNamErr    Bad file name
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBHSetFInfo
17
FUNCTION PBHSetFInfo (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HSetFileInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  32  ioFlFndrInfo    16 bytes
    Ņ>  48  ioDirID         long word
    Ņ>  72  ioFlCrDat       long word
    Ņ>  76  ioFlMdDat       long word

    PBHSetFInfo is identical to PBSetFInfo except that it accepts a
directory ID in ioDirID.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBSetFLock
17
FUNCTION PBSetFLock (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetFilLock

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioFVersNum      byte

    PBSetFLock locks the file having the name pointed to by ioNamePtr
(and on flat volumes, the version number ioFVersNum) on the volume
specified by ioVRefNum. Access paths currently in use arenÕt affected.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock

\ PBHSetFLock
17
FUNCTION PBHSetFLock (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HSetFLock

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  48  ioDirID         long word

    PBHSetFLock is identical to PBSetFLock except that it accepts a
directory ID in ioDirID.

Result codes    noErr       No error
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBRstFLock
17
FUNCTION PBRstFLock (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _RstFilLock

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioFVersNum      byte

    PBRstFLock unlocks the file having the name pointed to by ioNamePtr
(and on flat volumes, the version number ioFVersNum) on the volume
specified by ioVRefNum. Access paths currently in use arenÕt affected.

Result codes    noErr       No error
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock

\ PBHRstFLock
17
FUNCTION PBHRstFLock (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HRstFLock

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  48  ioDirID         long word

    PBHRstFLock is identical to PBRstFLock except that it accepts a
directory ID in ioDirID.

Result codes    noErr       No error
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock

\ PBSetFVers
17
FUNCTION PBSetFVers (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetFilType

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioVersNum       byte
    Ņ>  28  ioMisc          byte

    PBSetFVers has no effect on hierarchical volumes. On flat volumes,
PBSetFVers changes the version number of the file having the name
pointed to by ioNamePtr and version number ioVersNum, on the volume
specified by ioVRefNum, to the version number stored in the high-order
byte of ioMisc. Access paths currently in use arenÕt affected.

Result codes    noErr           No error
                bdNamErr        Bad file name
                dupFNErr        Duplicate file name and version
                extFSErr        External file system
                fLckdErr        File locked
                fnfErr          File not found
                nsvErr          No such volume
                ioErr           I/O error
                paramErr        No default volume
                vLckdErr        Software volume lock
                wPrErr          Hardware volume lock
                wrgVolTypErr    Attempt to perform hierarchical
                                operation on a flat volume
\ PBRename
17
FUNCTION PBRename (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _Rename

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  26  ioVersNum       byte
    Ņ>  28  ioMisc          pointer

    Given a pointer to a file name in ioNamePtr (and on flat volumes, a
version number in ioVersNum), PBRename changes the name of the file to
the name pointed to by ioMisc. (If the name pointed to by ioNamePtr
contains one or more colons, so must the name pointed to by ioMisc.)
Access paths currently in use arenÕt affected. Given a pointer to a
volume name in ioNamePtr or a volume reference number in ioVRefNum, it
changes the name of the volume to the name pointed to by ioMisc. If a
volume to be renamed is specified by its volume reference number,
ioNamePtr can be NIL.

Warning:  If a volume to be renamed is specified by its volume name, be
          sure that it ends with a colon, or Rename will consider it a
          file name.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirFulErr   File directory full
                dupFNErr    Duplicate file name and version
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                fsRnErr     Problem during rename
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBHRename
17
FUNCTION PBHRename (paramBlock: HParmBlkPtr; async: BOOLEAN) : OSErr;

Trap macro  _HRename

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  28  ioMisc      pointer
    Ņ>  48  ioDirID     long word

    PBHRename is identical to PBRename except that it accepts a
directory ID in ioDirID and can be used to rename directories as well as
files and volumes. Given a pointer to the name of a file or directory
in ioNamePtr, PBHRename changes it to the name pointed to by ioMisc.
Given a pointer to a volume name in ioNamePtr or a volume reference
number in ioVRefNum, it changes the name of the volume to the name
pointed to by ioMisc.

Warning:  PBHRename cannot be used to change the directory a file is in.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirFulErr   File directory full
                dirNFErr    Directory not found or incomplete pathname
                dupFNErr    Duplicate file name and version
                extFSErr    External file system
                fLckdErr    File locked
                fnfErr      File not found
                fsRnErr     Problem during rename
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBGetCatInfo
17
FUNCTION PBGetCatInfo (paramBlock: CInfoPBPtr; async: BOOLEAN): OSErr;

Trap macro  _GetCatInfo

Parameter block
    Files:                              Directories:
    Ņ>  12  ioCompletion    pointer Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer <Đ> 18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word    Ņ>  22  ioVRefNum       word
    <Ņ  24  ioFRefNum       word    <Ņ  24  ioFRefNum       word
    Ņ>  28  ioFDirIndex     word    Ņ>  28  ioFDirIndex     word
    <Ņ  30  ioFlAttrib      byte    <Ņ  30  ioFlAttrib      byte
    <Ņ  32  ioFlFndrInfo    16 bytes<Ņ  32  ioDrUsrWds      16 bytes
    <Đ> 48  ioDirID         long    <Đ> 48  ioDrDirID       long
    <Ņ  52  ioFlStBlk       word    <Ņ  52  ioDrNmFls       word
    <Ņ  54  ioFlLgLen       long
    <Ņ  58  ioFlPyLen       long
    <Ņ  62  ioFlRStBlk      word
    <Ņ  64  ioFlRLgLen      long
    <Ņ  68  ioFlRPyLen      long
    <Ņ  72  ioFlCrDat       long    <Ņ  72  ioDrCrDat       long
    <Ņ  76  ioFlMdDat       long    <Ņ  76  ioDrMdDat       long
    <Ņ  80  ioFlBkDat       long    <Ņ  80  ioDrBkDat       long
    <Ņ  84  ioFlXFndrInfo   16 bytes<Ņ  84  ioDrFndrInfo    16 bytes
    <Ņ  100 ioFlParID       long    <Ņ  100 ioDrParID       long
    <Ņ  104 ioFlClpSiz      long

    PBGetCatInfo gets information about the files and directories in a
file catalog. To determine whether the information is for a file or a
directory, test bit 4 of ioFlAttrib, as described in the section
ŌCInfoPBRecĶ. The information thatÕs returned for files is shown in the
left column, and the corresponding information for directories is shown
in the right column.

    If ioFDirIndex is positive, the File Manager returns information
about the file or directory whose directory index is ioFDirIndex in the
directory specified by ioVRefNum (this will be the root directory if a
volume reference number is provided).

    If ioFDirIndex is 0, the File Manager returns information about the
file or directory specified by ioNamePtr, in the directory specified by
ioVRefNum (again, this will be the root directory if a volume reference
number is provided).

    If ioFDirIndex is negative, the File Manager ignores ioNamePtr and
returns information about the directory specified by ioDirID.

    With files, PBGetCatInfo is similar to PBHGetFileInfo but returns
some additional information. If the file is open, the reference number
of the first access path found is returned in ioFRefNum, and the name of
the file is returned in ioNamePtr (unless ioNamePtr is NIL).

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
\ PBSetCatInfo
17
FUNCTION PBSetCatInfo (paramBlock: CInfoPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _SetCatInfo

Parameter block
    Files:                          Directories:
    Ņ>  12  ioCompletion    pointer Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word    <Ņ  16  ioResult        word
    <Đ> 18  ioNamePtr       pointer <Đ> 18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word    Ņ>  22  ioVRefNum       word
    Ņ>  30  ioFlAttrib      byte    Ņ>  30  ioFlAttrib      byte
    Ņ>  32  ioFlFndrInfo    16 bytesŅ>  32  ioDrUsrWds      16 bytes
    Ņ>  48  ioDirID         long    Ņ>  48  ioDrDirID       long
    Ņ>  72  ioFlCrDat       long    Ņ>  72  ioDrCrDat       long
    Ņ>  76  ioFlMdDat       long    Ņ>  76  ioDrMdDat       long
    Ņ>  80  ioFlBkDat       long    Ņ>  80  ioDrBkDat       long
    Ņ>  84  ioFlXFndrInfo   16 bytesŅ>  84  ioDrFndrInfo    16 bytes
    Ņ>  104 ioFlClpSiz      long

    PBSetCatInfo sets information about the files and directories in a
catalog. With files, itÕs similar to PBHSetFileInfo but lets you set
some additional information. The information that can be set for files
is shown in the left column, and the corresponding information for
directories is shown in the right column.

Result codes    noErr       No error
                bdNamErr    Bad file name
                dirNFErr    Directory not found or incomplete pathname
                extFSErr    External file system
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
\ PBCatMove
17
FUNCTION PBCatMove (paramBlock: CMovePBPtr; async: BOOLEAN) : OSErr;

Trap macro  _CatMove

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    Ņ>  22  ioVRefNum       word
    Ņ>  28  ioNewName       pointer
    Ņ>  36  ioNewDirID      long word
    Ņ>  48  ioDirID         long word

    PBCatMove moves files or directories from one directory to another.
The name of the file or directory to be moved is pointed to by
ioNamePtr; ioVRefNum contains either the volume reference number or
working directory reference number. A directory ID can be specified in
ioDirID. The name and directory ID of the directory to which the file
or directory is to be moved are specified by ioNewName and ioNewDirID.

    PBCatMove is strictly a file catalog operation; it does not actually
change the location of the file or directory on the disk. PBCatMove
cannot move a file or directory to another volume (that is, ioVRefNum is
used in specifying both the source and the destination). It also cannot
be used to rename files or directories; for that, use PBHRename.

Result codes    noErr       No error
                badMovErr   Attempt to move into offspring
                bdNamErr    Bad file name or attempt to move into a file
                dupFNErr    Duplicate file name and version
                fnfErr      File not found
                ioErr       I/O error
                nsvErr      No such volume
                paramErr    No default volume
                vLckdErr    Software volume lock
                wPrErr      Hardware volume lock
\ PBOpenWD
17
FUNCTION PBOpenWD (paramBlock: WDPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _OpenWD

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  18  ioNamePtr       pointer
    <Đ> 22  ioVRefNum       word
    Ņ>  28  ioWDProcID      long word
    Ņ>  48  ioWDDirID       long word

    PBOpenWD takes the directory specified by ioVRefNum, ioWDDirID, and
ioWDProcID and makes it a working directory. (You can also specify the
directory using a combination of partial pathname and directory ID.)  It
returns a working directory reference number in ioVRefNum that can be
used in subsequent calls.

    If a given directory has already been made a working directory using
the same ioWDProcID, no new working directory will be opened; instead,
the existing working directory reference number will be returned. If a
given directory was already made a working directory using a different
ioWDProcID, a new working directory reference number is returned.

Result codes    noErr       No error
                tmwdoErr    Too many working directories open
\ PBCloseWD
17
FUNCTION PBCloseWD (paramBlock: WDPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _CloseWD

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    Ņ>  22  ioVRefNum       word

    PBCloseWD releases the working directory whose working directory
reference number is specified in ioVRefNum.

Note:  If a volume reference number is specified in ioVRefNum, PBCloseWD
       does nothing.

Result codes    noErr   No error
                nsvErr  No such volume
\ PBGetWDInfo
17
FUNCTION PBGetWDInfo (paramBlock: WDPBPtr; async: BOOLEAN) : OSErr;

Trap macro  _GetWDInfo

Parameter block
    Ņ>  12  ioCompletion    pointer
    <Ņ  16  ioResult        word
    <Ņ  18  ioNamePtr       pointer
    <Đ> 22  ioVRefNum       word
    Ņ>  26  ioWDIndex       word
    <Đ> 28  ioWDProcID      long word
    <Đ> 32  ioWDVRefNum     word
    <Ņ  48  ioWDDirID       long word

    PBGetWDInfo returns information about the specified working
directory. The working directory can be specified either by its working
directory reference number in ioVRefNum (in which case ioWDIndex should
be 0), or by its index number in ioWDIndex. In the latter case, if
ioVRefNum is nonzero, itÕs interpreted as a volume specification (volume
reference number or drive number), and only working directories on that
volume are indexed.

    IOWDVRefNum always returns the volume reference number. IOVRefNum
returns a working directory reference number when a working directory
reference number is passed in that field; otherwise, it returns a volume
reference number. The volume name is returned in ioNamePtr.

    If IOWDProcID is nonzero, only working directories with that
identifier are indexed; otherwise all working directories are indexed.

Result codes    noErr   No error
                nsvErr  No such volume
\ PrOpen
18
PROCEDURE PrOpen;

    PrOpen prepares the Printing Manager for use. It opens the Printer
Driver and the printer resource file. If either of these items is
missing, or if the printer resource file is not properly formed, PrOpen
will do nothing, and PrError will return a Resource Manager result
code.
\ PrClose
18
PROCEDURE PrClose;

    PrClose releases the memory used by the Printing Manager. It closes
the printer resource file, allowing the file's resource map to be
removed from memory. It *** currently *** doesn't close the Printer
Driver, however, since the driver may have been opened before the
PrOpen call was issued.
\ PrintDefault
18
PROCEDURE PrintDefault (hPrint: THPrint);

    PrintDefault fills the fields of a print record with the current
default values stored in the printer resource file. HPrint is a handle
to the record, which may be a new print record that you've just
allocated or an existing one (from a document, for example).
\ PrValidate
18
FUNCTION PrValidate (hPrint: THPrint) : BOOLEAN;

    PrValidate checks the contents of a print record for compatibility
with the current version of the Printing Manager and with the installed
printer. If the record is valid, the function returns FALSE (no
change); if invalid, the record is adjusted to the current default
values, taken from the printer resource file, and the function returns
TRUE.

    PrValidate also updates the print record to reflect the current
settings in the style and job subrecords. These changes have no effect
on the function's Boolean result.
\ PrStlDialog
18
FUNCTION PrStlDialog (hPring: THPrint) : BOOLEAN;

    PrStlDialog conducts a style dialog with the user to determine the
paper size and paper orientation being used. The initial settings
displayed in the dialog box are taken from the current values in the
print record. If the user confirms the dialog, the results of the
dialog are saved in the print record and the function returns TRUE;
otherwise the print record is left unchanged and the function returns
FALSE.

(note)
    If the print record was taken from a document, you should
    update its contents in the document's file if PrStlDialog
    returns TRUE. This makes the results of the style dialog
    "stick" to the document.
\ PrJobDialog
18
FULNCTION PrJobDialog (hPrint: THPrint) : BOOLEAN;

    PrJobDialog conducts a job dialog with the user to determine the
printing quality, number of pages to print, and so on. The initial
settings displayed in the dialog box are taken from the current values
in the print reord. If the user confirms the dialog, both the print
record and the printer resource file are updated (so that the user's
choices "stick" to the printer) and the function returns TRUE;
otherwise the print record and printer resource file are left unchanged
and the function returns FALSE.

(note)
    If the job dialog is associated with your application's
    Print command, you should proceed with the requested
    printing operation id PrJobDialog returns TRUE. If the
    print record was taken form a document, you should update
    its contents in the document's file.
\ PrJobMerge
18
PROCEDURE PrJobMerge (hPringSrc,hPrintDst: THPrint):

    PrJobMerge copies the job subrecord from one print record
(hPrintSrc) to another (hPrintDst) and updates the destination record's
printer information, band information, and paper rectangle, based on
information in the job subrecord. This allows the information in the
job subrecord to be used for a group of related jobs.
\ PrOpenDoc
18
FUNCTION PrOpenDoc (hPrint: THPrint; pPrPort: TPPrPort; pIOBuf: Ptr)
        : TPPrPort;

    PrOpenDoc initializes a printing port for use in printing a document
makes it the current port, and returns pointer to it. HPrint is a
handle to the print record for this printing operation. The printing
port is customized for draft printing or spooling, depending on the
setting of th bJDocLoop field in the job subrecord. For spooling, the
spool file's name, volume reference number, and version number are
taken from the job subrecord.

    PPrPort is a pointer to the storage to be used for the printing
port. If this parameter is NIL, PrOpenDoc will allocate a new printing
port for you. Similarly, pIOBuf points to an area of memory to be used
as an input/output buffer; if it's NIL, PrOpenDoc will use the volume
buffer for the spool file's volume.

(note)
    The pPrPort and pIOBuf parameters are provided because
    both the printing port and the input/output buffer are
    nonrelocatable objects. To avoid cluttering the heap
    with such objects, you have the opportunity to allocate
    them yourself and pass them to PrOpenDoc. Most of the
    time you'll just set both of these parameters to NIL.

(note)
    Newly created printing ports use the system font (since
    they're grafPorts), but newly created windows use the
    application font. Be sure the font you use in the
    printing port is the same as the font in your application
    window if yuou want the text in both places to match.
\ PrOpenPage
18
PROCEDURE PrOpenPage (pPrPort: TPPrPort; pPageFrame: TPRect);

    PrOpenPage begins a new page in the document associated with the
given printing port. The page is printed only if it falls within the
page range designated in the job subrecord.

    For spooling, the pPageFrame parameter points to a rectangle that
will be used as the QuickDraw picture frame for this page:

    TYPE TPRect = ^Rect;

    When the spool file is later printed, this rectangle will be scaled
(via the QuickDraw DrawPicture procedure) to coincide with the page
rectangle in the printer ilnformation subrecord. Unless you want the
printout to be scaled, you should set pPageFrame to NIL--this uses the
curret page rectangle as the picture frame, and the page will be
printed with no scaling.
\ PrClosePage
18
PROCEDURE PrClosePage (pPrPort: TPPrPort);

    PrClosePage finishes up the current page of the document associated
with the given printing port. For draft printing, it ejects the page
from the printer and, if necessary, alerts the user to insert another;
for spooling, it closes the picture representing the current page.
\ PrCloseDoc
18
PROCEDURE PrCloseDoc (pPrPort: TPPrPort);

    PrCloseDoc finishes up the printing of the document associated with
the given printing port. For draft printing, it issues a form feed and
a reset command to the printer; for spooling, it closes the file if the
spooling was successfully completed or deletes it the file if the
spooling was unsuccessful.
\ PrPicFile
18
PROCEDURE PrPicFile (hPrint: THPrint; pPrPort: TPPrPort; pIOBuf: Ptr;
        pDevBuf: Ptr; VAR prStatus: TPrStatus);

    PrPicFile images and prints a spool file. HPrint is a handle to the
print record for this printing operation. The name, volume reference
number, and version number of the spool file will be taken from the job
subrecord of this print record. After printing is successfully
completed, the Printing Manager deletes the spool file from the disk.

    PPrPort is a pointer to the storage to be used for the printing port
for this operation. If this parameter is NIL, PrPicFile will allocate
its own printing port. Similarly, pIOBuf points to an area of memory
to be used as an input/output buffer for reading the spool file; if
it's NIL, PrPicFile will use the volume buffer for the spool file's
volume. PDevBuf points to a similar buffer (the "band buffer") for
holding the bit image to be printed; ifNIL, PrPicFile will allocate
its own buffer from the heap. As for PrOpenDoc, you'll normally want
to set all of these storage parameters to NIL.

(note)
    If you provide your own storage for pDevBuf, it has to be
    big enough to hold the number of bytes indicated by the
    iDevBytes field of the TPrXInfo subrecord of the print
    record.

(warning)
    Be sure not to pass, in pPrPort, a pointer to the same
    printing port you received from PrOpenDoc, the one you
    originally used to spool the file. If that earlier port
    was allocated by PrOpenDoc itself (that is, if the
    pPrPort parameter to PrOpenDoc was NIL), then PrCloseDoc
    will have disposed of the port, making your pointer to it
    invalid. PrPicFile initializes a fresh printing port of
    its own; you just provide the storage (or let PrPicFIle
    allocate it for itself). Of course, if you earlier
    provided your own storage to PrOpenDoc, there's no reason
    you can't use the same storage again for PrPicFile.

    The prStatus parameter is a printer status record that PrPicFile
will use to report on its progress. Your background procedure (if any)
can use this record to monitor the state of the printing operation.
\ PrError
18
FUNCTION PrError : INTEGER; [Pascal only]

    PrError returns the result code returned by the last Printing
Manager routine. The possible result codes are:

    CONST noErr       = 0;     {no error}
          iMemFullErr = -108;  {not enough heap space}

    and any Resource Manager result code. A result code of iMemFullErr
means that the Memory Manager was unable to fulfill a memory allocation
request by the Printing Manager.
\ PrSetError
18
PROCEDURE PrSetError (iErr: INTEGER); [Pascal Only]

    PrSetError stores the specified value into the global variable where
the Printing Manager keeps its result code. The main *** (currently
the only) *** use of this procedure is for canceling a printing
operation in progress. To do this, write

    PrSetError(iPrAbort)

where iPrAbort is the following predefined constant:

    CONST iPrAbort = 128;  {result code for halting printing}
\ PrDrvrOpen
18
PROCEDURE PrDrvrOpen;

    PrDrvrOpen opens the Printer Driver.
\ PrDrvrClose
18
PROCEDURE PrDrvrClose;

    PrDrvrClose closes the Printer Driver.
\ PrCtlCall
18
PROCEDURE PrCtlCall (iWhichCtl: INTEGER; lParam1,lParam2,lParam3):
                    LongInt);

    PrCtlCall calls the Printer Driver's control routine. IWhichCtl
designates the operation to be performed; the rest of the parameters
depend on the operation.
\ PrDrvrDCE
18
FUNCTION PrDrvrDCE : Handle;

    PrDrvrDCE returns a handle to the Printer Driver's device control
entry.
\ PrDrvrVers
18
FUNCTION PrDrvrVers : INTEGER;

    PrDrvrVers returns the version number of the Printer Driver in the
system resource file.

    The version number of the Printing Manager is available as the
predefined constant iPrRelease. You may want to compare the result of
PrDrvrVers with iPrRelease to see if the Printer Driver in the resource
file is the most recent version.
\ PrNoPurge
18
PROCEDURE PrNoPurge;

    PrNoPurge prevents the Printer Driver from being purged from the
heap.
\ PrPurge
18
PROCEDURE PrPurge;

    PrPurge allows the Printer Driver to be purged from the heap.
\ OpenDriver
19
FUNCTION OpenDriver (name: Str255; VAR refNum: INTEGER) : OSErr;

    OpenDriver opens the device driver specified by name and returns its
reference number in refNum.

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    dInstErr        Couldn't find driver in resource
                                    file
                    openErr         Driver cannot perform the
                                    requested reading or writing
                    unitEmptyErr    Bad reference number
\ CloseDriver
19
FUNCTION CloseDriver (refNum: INTEGER) : OSErr;

    CloseDriver closes the device driver having the reference number
refNum. Any pending I/O is completed, and the memory used by the
driver is released.


    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    dRemoveErr      Tried to remove an open driver
                    unitEmptyErr    Bad reference number
\ FSRead
19
FUNCTION FSRead (refNum: INTEGER; VARcount: LongInt; buffPtr: Ptr) :
        OSErr;

    FSRead attempts to read the number of bytes specified by the count
parameter from the device driver having the reference number refNum,
and transfer them to the data buffer pointed to by buffPtr. After the
read operation is completed, the number of bytes actually read is
returned in the count parameter.


    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    readErr         Driver can't respond to Read
                                    calls
\ FSWrite
19
FUNCTION FSWrite (refNum: INTEGR; VARcount: LongInt; buffPtr: Ptr) :
                    OSErr;

    FSWrite attempts to take the number of bytes specified by the count
parameter from the buffer pointed to by buffPtr and write them to the
open device driver having the reference number refNum. After the write
operation is completed, the number of bytes actually written is
returned in the count parameter.

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    writErr         Driver can't respond to Write
                                    calls
\ Control
19
FUNCTION COntrol (refNum: INTEGER; csCode: INTEGER; csParam: Ptr):
        OSErr;

    Control sends control information to the device driver haaving the
reference number refNum. The type of information sent is specified by
csCode, and the ilnformation itself is pointed to by csParam. The
values passed in csCode and pointed to by csParam depend on the driver
being called.


    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    controlErr      Driver can't respond to this
                                    Control call



\ Status
19
FUNCTION Status (refNum: INTEGER; csCode: INTEGER; csParam: Ptr) :
        OSErr;

    Status returns status information about the device driver having the
reference number refNum. The type of information returned is specified
by csCode, and the information itself is pointed to by csParam. The
values passed in csCode and pointed to by csParam depend on the driver
being called.

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    statusErr       Driver can't respond to this
                                    Status call
\ KillIO
19
FUNCTION KillIO (refNum: INTEGER) : OSErr;

    KillIO terminates all current and pending I/O with the device driver
having the reference number refNum.

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    unitEmptyErr    Bad reference number
                    controlErr      Driver can't respond to KillIO
                                    calls

(note)
    KillIO is actually a special type of PBControl call, and
    all information aabout PBControl calls applies equally to
    KillIO.
\ PBOpen
19
FUNCTION PBOpen (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Open

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 18  ioNamePtr   pointer
        <-- 24  ioRefNum    word
        --> 27  ioPermssn   byte

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    dInstErr        Couldn't find driver in resource
                                    file
                    openErr         Driver cannot perform the
                                    requested reading or writing
                    unitEmptyErr    Bad reference number


    PBOpen opens the device driver specified by ioNamePtr and returns
its reference number in ioRefNum. IOPermssn specifies the requested
read/write permission.
\ PBClose
19
FUNCTION PBCLose (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Close

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    dRemoveErr      Tried to remove an open driver
                    unitEmptyErr    Bad reference number


    PBClose closes the device driver having the reference number
ioRefNum. Any pending I/O is completed, and the memory used by the
driver is released.
\ PBRead
19
FUNCTION PBRead (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Read

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word
        --> 32  ioBuffer    pointer
        --> 36  ioReqCount  long word
        <-- 40  ioActCount  long word
        --> 44  ioPosMode   word
        <-> 46  ioPosOffset long word




    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    readErr         Driver can't respond to Read
                                    calls

    PBRead attempts to read ioReqCount bytes from the device driver
having the reference number ioRefNum, and transfer them to the data
buffer pointed to by ioBuffer. After the read operation is completed,
the number of bytes actually read is returned in ioActCount.

Advanced programmers:  If the driver is reading from a block device,
                       the byte offset from the position indicated by
                       ioPosMode, where the read should actually betwin,
                       is given by ioPosOffset.
\ PBWrite
19
FUNCTION PBWrite (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Write

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word
        --> 32  ioBuffer    pointer
        --> 36  ioReqCount  long word
        <-- 40  ioActCount  long word
        --> 44  ioPosMode   word
        --> 46  ioPosOffset long word

    Result codes    noErr       No error
            badUnitErr  Bad reference number
            notOpenErr  Driver isn't open
            unitEmptyErr    Bad reference number
            writErr Driver  can't respond to Write
                    calls

    PBWrite attempts to take ioReqCount bytes from the buffer pointed to
by ioBuffer and write them to the device driver having the reference
number ioRefNum. After the write operation is completed, the number of
bytes actually written is returned in ioActCount.

Advanced programmers:  If the driver is writing to a block device,
                       ioPosMode indicates whether the write should
                       begin relative to the beginning of the device or
                       the current position. The byte offset from the
                       position indicated by ioPosMode, where the write
                       should actually begin, is given by ioPosOffset.
\ PBControl
19
FUNCTION PBControl (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Control

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word
        --> 26  csCode      word
        --> 28  csParam     record

    Result codes    noErr           No error
                    badUnitErr      Bad reference number
                    notOpenErr      Driver isn't open
                    unitEmptyErr    Bad reference number
                    controlErr      Driver can't respond to this
                                    Control call


    PBControl sends control information to the device driver having the
reference number ioRefNum. The type of information sent is specified
by csCode, and the information itself begins at csParam. The values
passed in csCode and csParam depend on the driver being called.
\ PBStatus
19
FUNCTION PBStatus (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _Status

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word
        --> 26  csCode      word
        --> 28  csParam     record

    Result codes    noErr       No error
            badUnitErr  Bad reference number
            notOpenErr  Driver isn't open
            unitEmptyErr    Bad reference number
            statusErr   Driver can't respond to this
                    Status call

    PBStatus returns status information about the device driver having
the reference number ioRefNum. The type of information returned is
specified by csCode, and the information itself begins at csParam. The
values passed in csCode and csParam depend on the driver being called.
\ PBKillIO
19
FUNCTION PBKillIO (paramBlock: ParmBlkPtr; async: BOOLEAN) : OSErr;

    Trap macro  _KillIO

    Parameter block
        --> 12  ioCompletion    pointer
        <-- 16  ioResult    word
        --> 24  ioRefNum    word

    Result codes    noErr       No error
            badUnitErr  Bad reference number
            unitEmptyErr    Bad reference number
            controlErr  Driver can't respond to KillIO
                    calls

    KillIO stops any current I/O request being processed, and removes
all pending I/O requests from the I/O queue of the device driver having
the reference number ioRefNum. The completion routine of each pending
I/O request is called, with ioResult equal to the following result code:

    CONST abortErr = -27;

(note)
    KillIO is actually a special type of Control call, and
    all information about Control calls applies equally to
    KillIO.
\ DiskEject
20
FUNCTION DiskEject (drvNum: INTEGER) : OSErr;

    __________________________________________________________________

    Assembly-language note: DiskEject is equivalent to a Control
    call with csCode equivalent to the global constant ejectCode.
    __________________________________________________________________

    DiskEject ejects the disk from the internal drive if drvNum is 1, or
from the external drive if drvNum is 2.

    Result codes

            noErr       No error
            nsDrvErr    No such drive
\ SetTagBuffer
20
FUNCTION SetTagBuffer (buffPtr: Ptr) : OSErr;

    __________________________________________________________________

    Assembly-language note:  SetTagBuffer is equivalent to a Control
    call with csCode = 8.
    __________________________________________________________________

    An application can change the information used in the file tags
buffer by calling SetTagBuffer. The buffPtr parameter points to a
buffer that contains the information to be used. If buffPtr is NIL, the
information in the file tags buffer isn't changed.

    If buffPtr isn't NIL, every time the Disk Driver reads a sector from
the disk, it stores the file tags in the file tags buffer
by calling SetTagBuffer. The buffPtr parameter points to a buffer that
contains the information to be used. If buffPtr is NIL, the
information in the file tags buffer isn't changed.

    The contents of the buffer pointed to by buffPtr are overwritten at
the end of every read request (which can be composed of a number of
sectors) instead of at the end of every sector. Each read request
places 12 bytes in the buffer for each sector, always beginning at the
start of the buffer. This way an application can examine the file tags
for a number of sequentially read sectors. If a read request is
composed of a number of sectors, the Disk Driver reads 12 bytes from
the buffer for each sector. For example, for a read request of five
sectors, the Disk Driver will read 60 bytes from the buffer.

    __________________________________________________________________

    Assembly-language note:  An assembly-language program can change
    the information used in the file tags buffer by storing a
    pointer to the buffer containing the information in the global
    variable TagBufPtr. If TagBufPtr is 0, the information in the
    file tags buffer isn't changed.
    __________________________________________________________________

    Result codes

            noErr       No error
\ DriveStatus
20
FUNCTION DriveStatus (drvNum: INTEGER; VAR status: DrvSts) : OSErr;

    _________________________________________________________________

    Assembly-language note:  DriveStatus is equivalent to a Status
    call with csCode equivalent to teh globval constant drvStsCode.
    _________________________________________________________________

    DriveStatus returns information about the internal drive if drvNum
is 1, or about the external drive if drvNum is 2. The information is
returned in a record of type DrvSts:

TYPE DrvSts = RECORD
        track:      INTEGER;     {current track}
        writeProt:  SignedByte;  {bit 7=1 if volume is locked}
        diskInPlace:    SignedByte;  {disk in place}
        installed:  SignedByte;  {drive installed}
        sides:      SignedByte;  {bit 7=0 if single-sided drive}
        qLink:      QElmPtr;     {next queue entry}
        qType:      INTEGER;     {not used}
        dqDrive:    INTEGER;     {drive number}
        dqRefNum:   INTEGER;     {driver reference number}
        dqFSID:     INTEGER;     {file-system identifier}
        twoSideFmt: SignedByte;  {-1 if two-sided disk}
        needsFlush: SignedByte;  {reserved}
        diskErr:    INTEGER;     {error count}
      END;

    The diskInPlace field is 0 if there's no disk in the drive, 1 or 2
if there is a disk in the drive, or -4 to -1 if the disk was ejected in
the last 1.5 seconds. The installed field is 1 if the drive might be
connected to the Macintosh, and -1 if the drive isn't installed. 
The value oftwoSideFmt is valid only when diskInPlace = 2. The value
of diskErrs is incremented every time an error occurs internally within
the Disk Driver.

    Result codes

            noErr       No error
            nsDrvErr    No such drive
\ StartSound
21
PROCEDURE StartSound (synthRec: Ptr; numBytes: LONGINT; completionRtn:
        ProcPtr);

    StartSound begins producing the sound(s) described by the
synthesizer buffer pointed to by synthRec. NumBytes indicates the
length of the synthesizer buffer (in bytes), and completionRtn points to
a completion routine to be executed when the sound finishes:

    - If completionRtn is POINTER(-1), the sound will be produced
      synchronously.

    - If completionRtn is NIL, the sound will be produced
      asynchronously, but no completion routine will be executed.

    - Otherwise, the sound will be produced asynchronously and the
      routine pointed to by completionRtn will be executed when the
      sound finishes.

(warning)
    You may want the completion routine to start the next
    sound when one sound finishes, but beware:  Completion
    routines are executed at the interrupt level, and
    shouldn't make any calls to the Memory Manager. Be sure
    to preallocate all the space you'll need. Or, instead of
    using a completion routine to start the next sound, the
    completion routine can post an application-defined event
    and your application's main event lop can start the next
    sound when it gets the event.

    Because the type of pointer for each type of synthesizer buffer is
different and the type of the synthRec parameter is Ptr, you'll need to
do something like the following example (which applies to the free-form
synthesizer):

    VAR myPtr: Ptr;
        myHandle: Handle;
        myFFPtr: FFSynthPtr;
        ...
    myHandle := NewHandle(buffSize);     {allocate space for the buffer}
    HLock(myHandle);             {lock the buffer}
    myPtr := myHandle^;          {dereference the handle}
    myFFPtr := FFSynthPtr(myPtr);        {coerce type to FFSynthPtr}
    myFFPtr^.mode := ffMode;         {identify the synthesizer}
    ...                  {fill the buffer with values}
                         {describing the sound}
    StartSound(myPtr,buffSize,POINTER(-1));    {produce the sound}
    HUnlock(myHandle)              {unlock the buffer}

where buffSize is the length of the synthesizer record.

The sounds are generated as follows:

    - Free-form synthesizer:  The magnitudes described by each byte in
      the waveform description are genereated sequentially until the
      number of bytes specified by the numBytes paramaeter have been
      written.

    - Square-wave synthesizer:  The sounds described by each sound
      triplet are generaed sequentially until either the end of the
      buffer has been reached (indicated by a count, amplitude, and
      duration of 0 in the square-wave buffer), or the number of bytes
      specified by the numBytes parameter have been written.

    - Four-tone synthesizer:  All four sounds are generated for the
      length of time specified by the duration integer in the four-tone
      record.
\ StopSound
21
PROCEDURE StopSound;

    StopSound immediately stops the current StartSound call (if any),
executes the current StartSound call's completion routine (if any), and
cancels any pending asynchrounous StartSound calls.
\ SoundDone
21
FUNCTION SoundDone : BOOLEAN;

    SoundDone returns TRUE if the Sound Driver isn't currently producing
sound and there are no asynchronous StartSound calls pending; otherwise
it returns FALSE.
\ GetSoundVol
21
PROCEDURE GetSoundVol (VAR level: INTEGER);

    GetSoundVol returns the current speaker volume, from 0 (silence) to
7 (loudest).

    __________________________________________________________________

    Assembly-language note:  To set the speaker volume level from
    assembly language, call this Pascal routine from your program.
    As a side effect, it will set the low-order three bits of the
    global variable SdVolume to the specified level.
    __________________________________________________________________

(note)
    Your program shouldn't change the speaker volume unless
    it's a Control Panel-like desk accessory, since it's
    really up to the user to choose the desired volume level
    via the Control Panel.
\ RAMSDOpen
22
FUNCTION RAMSDOpen (whichPort: SPortSel; rsrcType: OSType; rsrcID:
        INTEGER) : OSErr;

    RAMSDOpen closes the ROM Serial Driver and opens the RAM input and
output drivers for the port identified by the whichPort parameter,
which must be a member of the SPortSel set:

    TYPE SPortSel = (sPortA, {modem port}
             sPortB  {printer port});

    RsrcType and rsrcID indicate the resource type and resource ID of
the RAM Serial Driver, which should be stored in your application's
resource file. (OSType is an Operating System Utility data type
declared the same as ResType in the Resource Manager.)

    Result codes

            noErr       No error
            openErr     Can't open driver
\ RAMSDClose
22
PROCEDURE RAMSDClose (whichPort: SPortSel);

    RAMSDClose closes the RAM input and output drivers for the port
identified by the whichPort parameter, which must be a member of the
SPortSel set (defined int eh description of RAMSDOpen above).
\ SerReset
22
FUNCTION SerReset (refNum: INTEGER; serConfig: INTEGER) : OSErr;

    SerReset resets and reinitializeds the input or output driver having
the reference number refNum according to the information in serConfig.
Figure 3 shows the format of serConfig.

    You can use the following predefined constants to set the values of
various bits of serConfig:

CONST   baud300     = 380;      {300 baud}
        baud600     = 189;      {600 baud}
        baud1200    = 94;       {1200 baud}
        baud1800    = 62;       {1800 baud}
        baud2400    = 46;       {2400 baud}
        baud3600    = 30;       {3600 baud}
        baud4800    = 22;       {4800 baud}
        baud7200    = 14;       {7200 baud}
        baud9600    = 10;       {9600 baud}
        baud19200   = 4;        {19200 baud}
        baud57600   = 0;        {57600 baud}
        stop10      = 16384;    {1 stop bit}
        stop15      = -32768;   {1.5 stop bits}
        stop20      = -16384;   {2 stop bits}
        noParity    = 8192;     {no parity}
        oddParity   = 4096;     {odd parity}
        evenParity  = 12288;    {even parity}
        data5       = 0;        {5 data bits}
        data6       = 2048;     {6 data bits}
        data7       = 1024;     {7 data bits}
        data8       = 3072;     {8 data bits}


    For example, the default setting of 9600 baud, eight data bits, two
stop bits, and no parity bit is equivalent to baud9600+data8+stop20+
noParity.
\ SerSetBuf
22
FUNCTION SerSetBuf (refNum: INTEGER; serBPtr: Ptr; serBLen: INTEGER) :
        OSErr;

    SerSetBuf specifies a new input buffer for the input driver having
the reference number refNum. SerBPtr points to the buffer, and serBLen
specifies the number of bytes in the buffer. If serBLen is 0, a
64-byte default buffer provided by the driver is used.

(warning)
    You must lock this buffer while it's in use.

    __________________________________________________________________

    Assembly-language note: SerSetBuf is equivalent to a Control
    call with csCode=9, csParam=serBPtr, and csParam+2=serBLen.
    __________________________________________________________________

    Result codes    noErr       No error
\ SerHShake
22
FUNCTION SerHShake (refNum: INTEGER; flags: SerShk) : OSErr;

    SerHShake sets handshake options and other control information, as
specified by the flags parameter, for the input or output driver having
the reference number refNum. The flags parameter has the following
data structure:

    TYPE SerShk = PACKED RECORD
            fXOn: Byte; {XOn/XOff output flow control flag}
            fCTS: Byte;     {CTS hardware handshake flag}
            xOn:  CHAR; {XOn character}
            xOff: CHAR; {XOff character}
            errs: Byte; {errors that cause abort}
            evts: Byte; {status changes that cause events}
            fInX: Byte; {XOn/XOff input flow control flag}
            null: Byte  {not used}
               END;

    If fXOn is nonzero, XOn/XOff output flow control is enabled; if fInX
is nonzero, XOn/XOff input flow control is enabled. XOn and xOff specify
the XOn character and XOff character used for XOn/XOff flow control.
If fCTS is nonzero, CTS hardware handshake is enabled. The errs field
indicates which errors will cause input requests to be aborted; for
each type of error, there's  a predefined constant in which the 
corresponding bit is set:

    CONST parityErr     = 16;   {set for parity error}
          hwOverrunErr  = 32;   {set for hardware overrun error}
          framingErr    = 64;   {set for framing error}

(note)
    The ROM Serial Driver doesn't support XOn/XOff input flow
    control or aborts caused by error conditions.

    The evts field indicates whether changes in the CTS or break status
will cause the Serial Driver to post device driver events; you can use
the following predefined constants to set or test the value of evts:

    CONST ctsEvent   = 32;  {set if CTS change will cause event to}
                {be posted}
          breakEvent = 128; {set if break status change will cause}
                    {event to be posted}


(warning)
    Use of this option is discouraged because of the long
    time that interrupts are disabled while such an event is
    posted.

    ___________________________________________________________________

    Assembly-language note:  SerHShake is equivalent to a Control
    call with csCode=10 and csParam through csParam+6 equivalent to
    the fields of a variable of type SerShk.
    ___________________________________________________________________

    Result codes    noErr       No error
\ SerSetBrk
22
FUNCTION SerSetBrk (refNum: INTEGER) : OSErr;

SerSetBrk sets break mode in the input or output driver having the
reference number refNum.

    ___________________________________________________________________

    Assembly-language note:  SerSetBrk is equivalent to a Control
    call with csCode=12.
    ___________________________________________________________________

    Result codes

            noErr       No error
\ SerClrBrk
22
FUNCTION SerClrBrk (refNumk: INTEGER) : OSErr;

    SerClrBrk clears break mode in the inplut or output driver having
the reference number refNum.

    __________________________________________________________________

    Assembly-language note:  SerClrBrk is equivalent to a Control
    call with csCode=11.
    __________________________________________________________________

    Result codes

        noErr       No error
\ SerGetBuf
22
FUNCTION SerGetBuf (refNum: INTEGER; VAR count: LONGILNT) ; OSErr;

    SerGetBuf returns, in the count parameter, the number of bytes in
the buffer of the input driver having the reference number refNum.

    ____________________________________________________________________

    Assembly-language note:  SerGetBuf is equivalent to a Status
    call with csCode=2. The number of bytes in the buffer is
    returned in csParam.
    ____________________________________________________________________

    Result codes

        noErr       No error
\ SerErrFlag
22
FUNCTION SerErrFlag (refNum: INTEGER; VAR serSta: SerStaRec) : OSErr;

    SerErrFlag returns in serSta three words of status information for
the input or output driver having the reference number refNum. The
serSta parameter has the following data structure:

    TYPE SerStaRec = PACKED RECORD
               cumErrs:   Byte; {cumulative errors}
               xOffSent:  Byte; {XOff sent as input flow}
                        { control}
               rdPend:    Byte; {read pending flag}
               wrPend:    Byte;     {write pending flag}
               ctsHold:   Byte; {CTS flow control hold flag}
               xOffHold:  Byte; {XOff received as output}
                            { flow control}
             END;

    CumErrs indicates which errors have occurred since the last time
SerErrFlag was called:

       CONST swOverrunErr = 1;  {set for software overrun error}
         parityErr    = 16; {set for parity error}
         hwOverrunErr = 32; {set for hardware overrun error}
         framingErr   = 64; {set for framing error}


    If the driver has sent an XOff character, xOffSent will be equal to
the following predefined constant:

    CONST xOffWasSent = $80;    {XOff character was sent}

    If the driver has a Read or Write call pending, rdPend or wrPend,
respectively, will be nonzero. If output has been suspended because
the hardware handshake was negated, ctsHold will be nonzero. If output
has been suspended because an XOff character was received, xOffHold
will be nonzero.

    __________________________________________________________________

    Assembly-language note:  SerStatus is equivalent to a Status
    call with csCode=8. The status information is returned in
    csParam through csParam+5.
    __________________________________________________________________

    Result codes    noErr       No error
\ MPPOpen
23
FUNCTION MPPOpen : OSErr;  [Not in ROM]

MPPOpen first checks whether the .MPP driver is already loaded; if it
is, MPPOpen does nothing and returns noErr. If MPP hasn't been loaded,
MPPOpen attempts to load it into the system heap. If it succeeds, it
then initializes the driver's variables and goes through the process of
dynamically assigning a node ID to that Macintosh. On a Macintosh 512K
or XL, it also loads the .ATP driver and NBP code into the system heap.

If serial port B isn't configured for AppleTalk, or is already in use,
the .MPP driver isn't loaded and an appropriate result code is
returned.

    Result codes    noErr       No error
            portInUse   Port B is already in use
            portNotCf   Port B not configured for AppleTalk




\ MPPClose
23
FUNCTION MPPClose : OSErr;   [Not in ROM]

MPPClose removes the .MPP driver, and any data structures associated
with it, from memory. If the .ATP driver or NBP code were also
installed, they'll also be removed. MPPClose also returns the use of
port B to the Serial Driver.

(warning)
    Since other co-resident programs may be using AppleTalk,
    it's strongly recommended that you never use this call. 
    MPPClose will completely disabale AppleTalk; the only way
    to restore ApleTalk is to call MPPOpen again.




\ LAPOpenProtocol
23
FUNCTION LAPOpenProtocol (theLAPType: ABBYte; protoPtr: Ptr) : OSErr;
        [Not in ROM]

LAPOpenProtocol adds the LAP protocol type specified by theLAPType to
the node's protocol table. If you provide a pointer to a protocol 
handler in protoPtr, ALAP will send each frame with a LAP protocol type
of theLAPType to that protocol handler.

If protoPtr is NIL, the default protocol handler will be used for
receiving frames with a LAP protocol type of theLAPType. In this case,
to receive a frame you must acall LAPRead to provide the default
protocol handler with a buffer for placing the data. If, however,
you've written your own protocol handler and protoPtr points to it,
your protocol handler will have the responsibility fro receiving the
frame and it's not necessary to call LAPRead.

    Result codes    noErr       No error
            lapProtErr  Error attaching protocol type




\ LAPWrite
23
FUNCTION LAPWrite (abRecord: ABRecHandle; async: BOOLEAN) : OSErr;
        [Not in ROM]

    ABusRecord
    ----------
       <--    abOpcode          {always tLAPWrite}
       <--    abResult          {result code}
       -->    abUserReference       {for your use}
       -->    lapAddress.dstNodeID      {destination node ID}
       -->    lapAddress.lapProtType    {LAP protocol type}
       -->    lapReqCount           {length of frame data}
       -->    lapDataPtr            {pointer to frame data}

LAPWrite sends a frame to another node. LAPReqCount and lapDataPtr
specify the length and location of the data to send. The
lapAddress.lapProtType field indicates the node ID of the node to
which the frame should be sent.

(note)
    The first two bytes of an ALAP frame's data must contain
    the length in bytes of the data, including the length
    bytes themselves.

    Result codes    noErr       No error
            excessCollsns   Unable to contact destination
                    node; packet not sent




\ LAPRead
23
FUNCTION LAPRead (abRecord: ABRecHandle; async: BOOLEAN) : OSErr;
        [Not in ROM]

    ABusRecord
    ----------
       <--    abOpcode      {always tLAPWrite}
       <--    abResult      {result code}
       -->    abUserReference   {for your use}
       <--    lapAddress.dstNodeID  {packet's destination node ID}
       <--    lapAddress.srcNodeID  {packet's source node ID}
       -->    lapAddress.lapProtType{LAP protocol type}
       -->    lapReqCount       {buffer size in bytes}
       <--    lapActCount       {number of frame data bytes actually }
                    {received}
       -->    lapDataPtr        {pointer to buffer}


LAPRead receives a frame from another node. LAPReqCount and lapDataPtr
specify the length and location of the buffer that will receive the
frame data. If the buffer isn't large enough to hold all of the
incoming frame data, the extra bytes wil be discarded and buf2SmallErr
will be returned. The number of bytes actually received is returned in
lapActCount. Only frames with LAP protocol type equal to
lapAddress.lapProtType will be received. The node number of the
frame's source and destination nodes are returned in
lapAddress.srcNodeID and lapAddress.dstNodeID respectively. You can
determine if the packet was broadcast to you by examining the value of
lapAddress.dstNodeID--if the packet was broadcast it's equal to 255,
otherwise it's equal to your node ID.

(note)
    You should issue LAPRead calls only for LAP protocol
    types that were opened (via LAPOpenProtocol) to use the
    default protocol handler.

    Result codes    noErr       No error
            buf2SmallErr    Frame too large for buffer
            readQErr    Invalid protocol type or
                    protocol type not found in table




\ LAPRdCancel
23
FUNCTION LAPRdCancel (abRecord: ABRecHandle) : OSErr;  [Not in ROM]

Given the handle to the ABusRecord of a previously made LAPRead call,
LAPRdCancel dequeues the LAPRead call, provided that a packet
satisfying the LAPRead has not already arrived. LAPRdCancel returns
noErr if the LAPRead call is successfully removed fdrom the queue. If
LAPRdCancel returns recNotFnd, check the abResult field to verify that
the LAPRead has been completed and determine its outcome.

    Result codes    noErr       No error
            readQErr    Invalid protocol type or
                    protocol type not found in table
            recNotFnd   ABRecord n ot found in queue




\ DDPOpenSocket
23
FUNCTION DDPOpenSocket (VAR theSocket: Byte; sktListener: Ptr) : OSErr;
        [Not in ROM]

DDPOpenSocket adds a socket and its socket listener to the socket
table. If theSocket is nonzero (it must be in the range of 64 to 127),
it specifies the socket's number. If theSocket is 0, DDPOpenSocket
dynamically assigns a socket number in the range 128 to 254, and
returns it in theSocket. SktListener contains a pointer to the socket
listener; if it'e NIL, the default listener will be used.

If you're using the default socket listener, you must then call DDPRead
to receive a datagram (in order to specify buffer space for the default
socket listener). If, however, you've written your own socket listener
and sktListener points to it, your listener will provide buffers for
receiving datagrams and you shouldn't use DDPRead calls.

DDPOpenSocket will return ddpSktErr if you pass the number of an
already opened socket, if you pass a socket number greater than 127, or
if the socket table is full.

(note)
    The range of static socket numbers 1 through 63 is
    reserved for use by AppleTalk. Socket numbers 64 through
    127 are available for unrestricted experimental use.

    Result codes    noErr       No error
            ddpSktErr   Socket error




\ DDPCloseSocket
23
FUNCTION DDPCloseSocket (theSocket: Byte) : OSErr;   [Not in ROM]

DDPCloseSocket removes the entry of the specified socket from the
socket table and cancels all pending DDPRead calls that have been made
to close a socket that isn't open, DDPCloseSocket will return
ddpSktErr.

    Result codes    noErr       No error
            ddpSktErr   Socket error



\ DDPWrite
23
FUNCTION DDPWrite (abRecord: ABRecfHandle; doChecksum: BOOLEAN; async:
        BOOLEAN) : OSErr;   [Not in ROM]

    ABusRecord
    ----------
       <--    abOpcode      {always tDDPWrite}
       <--    abResult      {result code}
       -->    abUserReference   {for your use}
       -->    ddpType       {DDP protocol type}
       -->    ddpSocket         {source socket number}
       -->    ddpAddress        {destination socket address}
       -->    ddpReqCount       {length of datagram data}
       -->    ddpDataPtr        {pointer to buffer}

DDPWrite sends a datagram to another socket. DDPReqCount and
ddpDataPtr specify the length and location of the data to send. The
ddpType field indicates the DDP protocol type of the frame, and
ddpAddress is the complete internet address of the socket to which the
datagram should be sent. DDPSocket specifies the socket from which the
datagram should be sent. Datagrams sent over the internet to a node on
an AppleTalk network different from the sending node's network have an
optional software checksum to detect errors that might occur inside the
intermediate bridges. If doChecksum is TRUE, DDPWrite will compute
this checksum; if it's FALSE, this software checksum feature is
ignored.

(note)
    The destination socket can't be in the same node as the
    program making the DDPWrite call.

    Result codes    noErr       No error
            ddpLenErr   Datagram length too big
            ddpSktErr   Source socket not open



\ DDPRead
23
FUNCTION DPRead (abRecord: ABRecfHandle; retChecksum: BOOLEAN; async:
        BOOLEAN) : OSErr;   [Not in ROM]

    ABusRecord
    ----------
       <--    abOpcode      {always tDDPWrite}
       <--    abResult      {result code}
       -->    abUserReference   {for your use}
       <--    ddpType       {DDP protocol type}
       -->    ddpSocket         {listening socket number}
       <--    ddpAddress        {source socket address}
       -->    ddpReqCount       {buffer size in bytes}
       <--    ddpActCount       {number of bytes actually received}
       -->    ddpDataPtr        {pointer to buffer}
       <--    ddpNodeID     {original destination node ID}


DDPRead receives a datagram from another socket. The length and
location of the buffer that will receive the data are specified by
ddpReqCount and ddpDataPtr, respectively. If the buffer isn't large
enough to hold all of the incoming frame data, the extra bytes will be
discarded and buf2SmallErr will be returned. The numbr of bytes
actually received is returned in ddpActCount. DDPSocket specifies the
socket to receive the datagram (the "listening" socket). The node to
which the packet was sent is returned in ddpNodeID; if the packet was
broadcast ddpNodeID will contain 255. The address of the socket that
sent the packet is returned in ddpAddress. If retCksumErrs is FALSE,
DDPRead will discard any packets received with an invalid checksum and
inform the caller of the error. If retCksumErr is TRUE, DDPRead will
deliver all packets, regardless of whether the checksum is valid or
not; it will also notify the caller when there's a checksum error.

(note)
    The sender of the datagram must be in a different node
    from the receiver. Youk should issue DDPRead calls only
    for receiving datagrams for sockets opened with the
    default socket listener; see the description of
    DDPOpenSocket.

(note)
    If DDPRead returns buf2SmallErr, it will deliver packets
    even if retCksukmErrs is FALSE.

    Result codes    noErr       No error
            buf2SmallErr    Datagram too large for buffer
            cksumErr    Checksum error
            ddpLenErr   Datagram length too big
            ddpSktErr   Socket error
            readQErr    Invalid socket or
                    socket not found in table



\ DDPRdCancel
23
FUNCTION DDPRdCancel (abRecord: ABRecHandle) : OSErr;   [Not in ROM]

Given the handle to the ABusRecord of a previously made DDPRead call,
DDPRdCancel dequeues the DDPRead call, provided that a packet
satisfying the DDPRead hasn't already arrived. DDPRdCancel returns
noErr if the DDPRead call is successfully removed from the queue. If
DDPRdCancel returns recNotFnd, check the abResult field of abRecord to
verify that the DDPRead has been completed and determine its outcome.


    Result codes    noErr       No error
            readQErr    Invalid socket or
                    socket not found in table
            recNotFnd   ABRecord not found in queue



\ ATPLoad
23
FUNCTION ATPLoad : OSErr;   [Not in ROM]

ATPLoad first verifies that the .MPP driver is loaded and running. If
it isn't, ATPLoad verifies that port B is configured for AppleTalk, and
is not in use, and then loads MPP into the system heap.

ATPLoad then loads the .ATP driver, unless it's already in memory. On
a Macintosh 128K, ATPLoad reads the .ATP driver from the system
resource file into the application heap; on a Macintosh 512K or XL, ATP
is read into the system heap.

(note)
    On a Macintosh 512K or XL, ATPLoad and MPPOpen perform
    essentially the same function.



    Result codes    noErr       No error
            portInUse   Port B is already in use
            portNotCf   Port B not configured for AppleTalk





\ ATPUnload
23
FUNCTION ATPUnload : OSErr;   [Not in ROM]

ATPUnload makes the .ATP driver purgeable; the space isn't actually
released by the Memory Manager until necessary.

(note)
    This call applies only to a Macintosh 128K; on a
    Macintosh 512K or Macintosh XL, ATPUnload has no effect.

    Result codes    noErr       No error



\ ATPOpenSocket
23
FUNCTION ATPOpenSocket (addrRcvd: AddrBlock; VAR atpSocket: Byte) :
        OSErr;   [Not in ROM]

ATPOpenSocket opens a socket for the purpose of receiving requests.
ATPSocket contains the socket number of the socket to open; if it's 0,
a number is dynamically assigned and returned in atpSocket. AddrRcvd
contains a filter of the sockets from which requests will be accepted.
A 0 in the network number, node ID, or socket number field of the
addrRcvd record acts as a "wild card"; for instance, a 0 in the socket
number field means that requests will be accepted from all sockets in
the node(s) specified by the network and node fields.

    Result codes    noErr       No error
            tooManySkts Socket table ful
            noDataArea  Too many outstanding ATP calls

(note)
    If you're only going to send requests and receive
    responses to these requests, you don't need to open an
    ATP socket. When you make the ATPSndRequest or
    ATPRequest call, ATP automatically opens a dynamically
    assigned socket for that purpose.



\ ATPCloseSocket
23
FUNCTION ATPCLoseSocket (atpSocket: Byte) : OSErr;   [Not in ROM]

ATPCloseSocket closes the responding socket whose number is specified
by atpSocket. It releases the data structures associated with all
pending, asynchronous calls involving that socket; these pending calls
are completed immediately and return the result code sktClosed.

    Result codes    noErr       No error
            noDataArea  Too many outstanding ATP calls



\ ATPSndRequest
23
FUNCTION ATPSndRequest (abRecord: ABRecHandle; async: BOOLEAN) : OSErr;
        [Not in ROM]

    ABusRecord
    ----------
       <--  abOpcode    {always tATPSndRequest}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  atpAddress  {destination socket address}
       -->  atpReqCount {request size in bytes}
       -->  atpDataPtr  {pointer to buffer}
       -->  atpRspBDSPtr    {pointer to response BDS}
       -->  atpUserData {user bytes}
       -->  atpXO       {exactly-once flag}
       <--  atpEOM      {end-of-message flag}
       -->  atpTimeOut  {retry timeout interval in seconds}
       -->  atpRetries  {maximum number of retries}
       -->  atpNumBufs  {number of elements in response BDS}
       <--  atpNumRsp   {number of response packets actually }
                {received}

ATPSndRequest sends a request to another socket. ATPAddress is the
internet address of the socket to which the request should be sent.
ATPDataPtr and atpReqCount specify the location and size of a buffer
that contains the request information to be sent. ATPUserData contains
the user bytes for the ATP header.

ATPSndRequest requires you to allocate a response BDS. ATPRspBDSPtr is
a pointer to the response BDS; atpNumBufs indicates the number of BDS
elements in the BDS (this is also the maximum number of response
datagrams that will be accepted). The number of response datagrams
actually received is returned in atpNumRsp; if a nonzero value is
returned, you can examine the response BDS to determine which packet
of the transaction were actually received. If the number returned is
less than requested, one of the folowing is true:

    - Some of the packets have been lost and the retry count has been
      exceeded.

    - ATPEOM is TRUE; this means that the response consisted of fewer
      packets than were expected, but that all packets sent were
      received (the last packet came with the atpEOM flag set).

ATPTimeOut indicates the length of time that ATPSndRequest should wait
for a response before retransmitting the request. ATPRetries indicates
the maximum number of retries ATPSndRequest shoud attempt. ATPXO
should be TRUE if you want the request to be part of an exactly-once
transaction.

ATPSndRequest completes when either the transaction is completed or the
retry count is exceeded.

    Result codes    noErr       No error
            reqFailed   Retry count exceeded
            tooManyReqs Too many concurrent requests
            noDataArea  Too many outstanding ATP calls



\ ATPRequest
23
FUNCTION ATPRequest (abRecord: ABRecHandle; async: BOOLEAN) : OSErr;
        [Not in ROM]

    ABusRecord
    ----------
       <--  abOpcode    {always tATPRequest}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  atpAddress  {destination socket address}
       -->  atpReqCount {request size in bytes}
       -->  atpDataPtr  {pointer to buffer}
       <--  atpActCount {number of bytes actually received}
       -->  atpUserData {user bytes}
       -->  atpXO       {exactly-once flag}
       <--  atpEOM      {end-of-message flag}
       -->  atpTimeOut  {retry timeout interval in seconds}
       -->  atpRetries  {maximum number of retries}
       <--  atpRspUData {user bytes received in transaction}
                { response}
       -->  atpRspBuf   {pointer to response message buffer}
       -->  atpRspSize  {size of response message buffer}

ATPRequest is functionally analogous to ATPSndRequest. It sends a
request to another socket, but doesn't require the caller to set up and
use the BDS data structure to describe the response buffers.
ATPAddress indicates the socket to which the request should be sent.
ATPDataPtr and atpReqCount specify the location and size of a buffer
that contains the request information to be sent. ATPUserData contains
the uset bytes to be sent in the request's ATP header. ATPTimeOut
indicates the length of time that ATPRequest should wait for a response
before retransmitting the request. ATPRetries indicates the maximum
number of retries ATPRequest should attempt.

To use this call, you must have an area of contiguous buffer space
that's large enough to receive all expected datagrams. The various
datagrams will be assembled in this buffer and returned to you as a
complete message upon completion of the transaction. The address and
size of this buffer are pased in atpRspBuf and atpRspSize,
respectively. Upon completion of the call, the size ofthe received
response message is returned in atpActCount. The user bytes received
in the ATP header of the first response packet are returned in
atpRspUData. ATPXO should be TRUE if you want the request to be part
of an exactly-once transaction.

Although you don't provide a BDS, ATPRequest in fact creates one and
calls the .ATP driver (as in an ATPSndRequest call). For this reason,
the abRecord fields atpRspBDSPtr and atpNumBufs are used by ATPRequest;
you should not expect these fields to remain unaltered during or after
the function's execution.

For ATPRequest to receive and correctly deliver the response as a
single message, the responding end must, upon receiving the request
(with an ATPGetRequest call), generate the complete response as a
complete message in a single buffer and then call ATPResponse.

(note)
    The responding end could also use ATPSndRsp and ATPAddRsp
    provided that each response packet (except the last one)
    contains exactly 578 ATP data bytes; the last packet in
    the response can contain less than 578 ATP data bytes.
    Also, if this method is used, only the ATP user bytes of
    the first response packet will be delivered to the
    requester; any information in the user bytes of the
    remaining response packets will not be delivered.

ATPRequest completes when either the transaction is completed or the
retry count is exceeded.

    Result codes    noErr       No error
            reqFailed   Retry count exceeded
            tooManyReqs Too many concurrent requests
            sktClosed   Socket closed by a cancel call
            noDataArea  Too many outstanding ATP calls




\ ATPReqCancel
23
FUNCTION ATPReqCancel (abRecord: ABRecHandle; async: BOOLEAN) : OSErr;
        [Not in ROM]

Given the handle to the ABusRecord of a previously made ATPSndRequest
or ATPRequest call, ATPReqCancel dequeues the ATPSndRequest or
ATPRequest call, provided that the call hasn't already completed.
ATPReqCancel returns noErr if the ATPSndRequest or ATPRequest call is
successfully removed from the queue. If it returns cbNotFound, check
the abResult field of abRecord to verify that the ATPSndRequest or
ATPRequest call has been completed and determine its outcome.

    Result codes    noErr       No error
            cbNotFound  ATP control block not found




\ ATPGetRequest
23
FUNCTION ATPGetRequest (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]

    ABusRecord
    ----------
       <--  abOpcode    {always tATPGetRequest}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  atpSocket   {listening socket number}
       <--  atpAddress  {source socket address}
       -->  atpReqCount {buffer size in bytes}
       -->  atpDataPtr  {pointer to buffer}
       <--  atpBitMap   {transaction bit map}
       <--  atpTransID  {transaction ID}
       <--  atpActCount {number of bytes actually received}
       <--  atpUserData {user bytes}
       <--  atpXO       {exactly-once flag}

ATPGetRequest sets up the mechanism to receive a request sent by either
an ATPSndRequest or an ATPRequest call. ATPSocket contains the socket
number of the socket that should listen for a request; this socket must
already have been opened by calling ATPOpenSocket. The address of the
socket from which the request was sent is returned in atpAddress.
ATPDataPtr specifies a buffer to store the incoming request;
atpReqCount indicates the size of the buffer in bytes. The number of
bytes actually received in the request is returned in atpActCount.
ATPUserData contains the user bytes from the ATP header. The
transaction bit map is returned in atpBitMap. The transaction ID is
returned in atpTransID. ATPXO will be TRUE if the request is part of
an exactly-once transaction.

ATPGetRequest completes when a request is received. To cancel an
asynchronous ATPGetRequest call, you must call ATPCloseSocket, but this
cancels all pending calls involving that socket.


    Result codes    noErr       No error
            badATPSkt   Bad responding socket
                sktClosed   Socket closed by a cancel call




\ ATPSndRsp
23
FUNCTION ATPSndRsp (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]


    ABusRecord
    ----------
       <--  abOpcode    {always tATPSndRsp}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  atpSocket   {responding socket number}
       -->  atpAddress  {destination socket address}
       -->  atpRspBDSPtr    {pointer to response BDS}
       -->  atpTransID  {transaction ID}
       -->  atpEOM      {end-of-message flag}
       -->  atpNumBufs  {number of response packets being }
                {sent}
       -->  atpBDSSize  {number of elements in response BDS}


ATPSndRsp sends a response to another socket. ATPSocket contains the
socket number from which the response should be sent and atpAddress
contains the internet address of the socket to which the response
should be sent. ATPTransID must contain the transaction ID. ATPEOM is
TRUE if the response BDS contains the final packet in a transaction
composed of a group of packets and the number of packets in the
response is less than expected. ATPRspBDSPtr points to the buffer data
structure containing the responses to be sent. ATPBDSSize indicates
the number of elements in the response BDS, and must be in the range 1
to 8. ATPNumBufs indicates the number of response packets being sent
with this call, and must be in the range 0 to 8.

(note)
    In some situations, you may want to send only part (or
    possibly none) of your response message back immediately.
    For instance, you might be requested to send back seven
    disk blocks, but have only enough internal memory to
    store one block. In this case, set atpBDSSize to 7
    (total number of response packets), atpNumBufs to 0
    (number of response packets currently being sent), and
    call ATPSndRsp. Then as you read in one block at a time,
    call ATPAddRsp until all seven response datagrams have
    been sent.

During exactly-once transactions, ATPSndRsp won't complete until the
release packet is received or the release timer expires.


    Result codes    noErr       No error
            badATPSkt   Bad responding socket
            noRelErr    No release received
                sktClosed   Socket closed by a cancel call
            noDataArea  Too many outstanding ATP calls



\ ATPAddRsp
23
FUNCTION ATPAddRsp (abRecord: ABRecHandle) : OSErr;   [Not in ROM]


    ABusRecord
    ----------
       <--  abOpcode    {always tATPAddRsp}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  atpSocket   {responding socket number}
       -->  atpAddress  {destination socket address}
       -->  atpReqCount {buffer size in bytes}
       -->  atpDataPtr  {pointer to buffer}
       -->  atpTransID  {transaction ID}
       -->  atpUserData {user bytes}
       -->  atpEOM      {end-of-message flag}
       -->  atpNumRsp   {sequence number}

ATPAddRsp sends one additional response packet to a socket that has
already been sent the initial part of a response via ATPSndRsp.
ATPSocket contains the socket number from which the response should be
sent and atpAddress contains the internet address of the socket to
which the response should be sent. ATPTransID must contain the
transaction ID. ATPDataPtr and atpReqCount specify the location and
size of a buffer that contains the information to send; atpNumRsp is
the sequence number of the response. ATPEOM is TRUE if this repsonse
datagram is the final packet in a transaction composed of a group of
packets. ATPUserData contains the user bytes to be sent in this
response datagram's ATP header.

(note)
    No BDS is needed with ATPAddRsp because all pertinent
    information is passed within the record.


    Result codes    noErr       No error
            badATPSkt   Bad responding socket
            badBuffNum  Bad sequence number
            noSendResp  ATPAddRsp issued before ATPSndRsp
            noDataArea  Too many outstanding ATP calls




\ ATPResponse
23
FUNCTION ATPResponse (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]


    ABusRecord
    ----------
       <--  abOpcode    {always tATPResponse}
       <--  abResult    {result code}
       -->  abUserReference {for your use}
       -->  aptSocket   {responding socket number}
       -->  atpAddress  {destination socket address}
       -->  atpRspUData {user bytes sent in transaction}
                { response}
       -->  atpRspBuf   {pointer to response message buffer}
       -->  atpRspSize  {size of response message buffer}

ATPResponse is functionally analogous to ATPSndRsp. It sends a
response to a socket, but doesn't require the caller to provide a BDS.
ATPAddress must contain the complete network address of the socket to
which the response should be sent (the socket on which the corresponding
ATPGetRequest was issued). ATPRspBuf points to the buffer containing
the response message; the size of this buffer must be passed in
atpRspSize. The four user bytes to be sent in the ATP header of the
first response packet are passed in atpRspUData. The last packet of
the transaction response is sent with the EOM flag set.

Although you don't provide a BDS, ATPResponse in fact creates one and
calls the .ATP driver (as in an ATPSndRsp call). For this reason, the
abRecord fields atpRspBDSPtr and atpNumBufs are used by ATPResponse;
you should not expect these fields to remain unaltered during or after
the function's execution.

During exactly-once transactions ATPResponse won't complete until the
release packet is received or the release timer expires.

(warning)
    The maximum permissible size of the response message is
    4624 bytes.


    Result codes    noErr       No error
            badATPSkt   Bad responding socket
            noRelErr    No release received
            atpLenErr   Response too big
                sktClosed   Socket closed by a cancel call
            noDataArea  Too many outstanding ATP calls




\ ATPRspCancel
23
FUNCTION ATPRspCancel (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]

Given the handle to the ABusRecord of a previously made ATPSndRsp or
ATPResponse call, ATPRspCancel dequeues the ATPSndRsp or ATPResponse
call, provided that the call hasn't already completed. ATPRspCancel
returns noErr if the ATPSndRsp or ATPResponse call is successfully
removed from the queue. If it returns cbNotFound, check the abResult
field of abRecord to verify that the ATPSndRsp or ATPResponse call has
been completed and determine its outcome.


    Result codes    noErr       No error
            cbNotFound  ATP control block not found
            noDataArea  Too many outstanding ATP calls




\ NBPRegister
23
FUNCTION NBPRegister (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]


    ABusRecord
    ----------
       <--  abOpcode        {always tNBPRegister}
       <--  abResult        {result code}
       -->  abUserReference     {for your use}
       -->  nbpEntityPtr        {pointer to entity name}
       -->  nbpBufPtr       {pointer to buffer}
       -->  nbpBufSize      {buffer size in bytes}
       -->  nbpAddress.aSocket  {socket address}
       -->  nbpRetransmitInfo   {retransmission information}

NBPRegister adds the name and address of an entity to the node's names
table. NBPEntityPtr points to a variable of type EntityName containing
the entity's name. If the name is already registered, NBPRegister
returns the result code nbpDuplicate. NBPBufPtr and nbpBufSize
specify the location and size of a buffer for NBP to use internally.
The buffer must contain at least 12 bytes plus the length of the entity
name.

(warning)
    This buffer must not be altered or released until the
    name is removed from the names table via an NBPRemove
    call. If you allocate the buffer through a NewHandle
    call, the handle must be locked as long as the name is
    registered.

    Result codes    noErr       No error
            nbpDuplicate    Duplicate name already exists




\ NBPLookup
23
FUNCTION NBPLookup (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]


    ABusRecord
    ----------
       <--  abOpcode        {always tNBPLookup}
       <--  abResult        {result code}
       -->  abUserReference     {for your use}
       -->  nbpEntityPtr        {pointer to entity name}
       -->  nbpBufPtr       {pointer to buffer}
       -->  nbpBufSize      {buffer size in bytes}
       <->  nbpDataField        {number of addresses received}
       -->  nbpRetransmitInfo   {retransmission information}

NBPLookup returns the addresses of all entities with a specified name.
NBPEntityPtr points to a variable of type EntityName containing the
name of the entity whose address should be returned. (Meta-characters
are allowed in the entity name.)  NBPBufPtr and NBPBufSize contain the
location and size of an area of memory in which the entities' addresses
should be returned. NBPDataField indicates the maximum number of
matching names to find addresses for; the actual number of addresses
found is returned in NBPDataField. NBPRetransmitInfo contains the
retry interval and the retry count.

    Result codes    noErr       No error
            nbpBuffOvr  Buffer overflow



\ NBPExtract
23
FUNCTION NBPExtract (theBuffer: Ptr; numInBuf: INTEGER; whichOne:
        INTEGER; VAR abEntityName; VAR address: AddrBlock)
        : OSErr;   [Not in ROM]

NBPExtract retruns one address from the list of addresses returned by
NBPLookup. TheBuffer and numInBuf indicate the location and number of
tuples in the buffer. WhichOne specifies which one of the tuples in
the buffer should be returned in the abEntity and adress parameters.

    Result codes    noErr       No error
            extractErr  Can't find tuple in buffer



\ NBPConfirm
23
FUNCTION NBPConfirm (abRecord: ABRecHandle; async: BOOLEAN) :
        OSErr;   [Not in ROM]

    ABusRecord
    ----------
       <--  abOpcode        {always tNBPConfirm}
       <--  abResult        {result code}
       -->  abUserReference     {for your use}
       -->  nbpEntityPtr        {pointer to entity name}
       <--  nbpDataField        {number of addresses received}
       -->  nbpAddress      {socket address}
       -->  nbpRetransmitInfo   {retransmission information}

NBPConfirm confirms that an entity known by name and address still
exists (is still entered in the names directory). NBPEntityPtr points
to a variable of type EntityName that contains the name to confirm, and
nbpAddress specifies the address to be confirmed. (No meta-characters
are allowed in the entity name.)  NBPRetransmitInfo contains the retry
interval and the retry count. The correct socket number of the entity
is returned in nbpDataField. NBPConfirm is more efficient than
NBPLookup in terms of network traffic.


    Result codes    noErr       No error
            nbpConfDiff Name confirmed for different socket
            nbpNoConfirm    Name not confirmed



\ NBPRemove
23
FUNCTION NBPRemove (abEntity: EntityPtr) : OSErr;   [Not in ROM]

NBPRemove removes an entity name from the names table of the caller's
node.


    Result codes    noErr       No error
            nbpNotFound Name not found



\ NBPLoad
23
FUNCTION NBPLoad : OSErr;   [Not in ROM]

On a Macintosh 128K, NBPLoad reads the AppleTalk Manager's NBP code
from the system resource file into the application heap. On a
Macintosh 512K or XL, NBPLoad has no effect since the NBP code should
have already been loaded when the .MPP driver was opened. Normally
you'll never need to call NBPLoad because the AppleTalk Manager calls
it when necessary.

    Result codes    noErr       No error



\ NBPUnload
23
FUNCTION NBPUnload : OSErr;   [Not in ROM]

NBPUnload makes the NBP code purgeable; the space isn't actually
released by the Memory Manager until necessary.

(note)
    This call applies only to a Macintosh 128K; on a
    Macintosh 521K or Macintosh XL, NBPUnload has no effect.

    Result codes    noErr       No error




\ GetNodeAddress
23
FUNCTION GetNodeAddress (VAR myNode,myNet: INTEGER) : OSErr;[Not in ROM]

GetNodeAddress returns the current node ID and network number of the
caller. If the .MPP driver isn't installed, it returns noMPPErr. If
myNet contains 0, this means that a bridge hasn't yet been found.

    Result codes    noErr       No error
            noMPPErr    MP driver not installed



\ IsMPPOpen
23
FUNCTION IsMPPOpen : BOOLEAN;   [Not in ROM]

IsMPPOpen returns TRUE if the .MPP driver is loaded and running.



\ IsATPOpen
23
IsATPOpen : BOOLEAN;   [Not in ROM]

IsATPOpen returns TRUE if the .ATP driver is loaded and running.


\ VInstall
24
FUNCTION VInstall (vblTaskPtr: QElemPtr) : OSErr;

    _________________________________________________________________

    Trap macro  _VInstall

    On entry    A0:  vblTaskPtr (pointer)

    On exit     D0:  result code (integer)
    _________________________________________________________________

    VInstall adds the task described by vblTaskPtr to the vertical
retrace queue. Your application must fill in all fields of the task
except qLink. VInstall returns one of the result codes listed below.

    Result codes

            noErr       No error
            vTypErr     QType field isn't ORD(vType)

\ VRemove
24
FUNCTION VRemove (vblTaskPtr: QElemPtr) : OSErr;

    _________________________________________________________________

    Trap macro  _VRemove

    On entry    A0:  vblTaskPtr (pointer)

    On exit     D0:  result code (integer)
    _________________________________________________________________


    Result codes

            noErr       No error
            vTypErr     QType field isn't ORD(vType)
            qErr        Task entry isn't in the queue
\ GetVBLQHdr
24
FUNCTION GetVBLQHdr : QHdrPtr;   [Pascal only]

    GetVBLQHdr returns a pointer to the vertical retrace queue.
\ HandToHand
25
FUNCTION HandToHand (VAR theHndl: Handle) : OSErr;

    _________________________________________________________________

    Trap macro  _HandToHand

    On entry    A0:  theHndl (handle)

    On exit     A0:  theHndl (handle)
                D0:  result code (word)
    __________________________________________________________________

    HandToHand copies the information to which theHndl is a handle and
returns a new handle to the copy in theHndl. Since HandToHand replaces
the input parameter with a new handle, you should retain the original
value of the input parameter somewhere else, or you won't be able to
access it. For example:

    VAR x,y: Handle;
        err: OSErr;

    y := x;
    err := HandToHand(y)

    The original handle remains in x while y becomes a different handle
to identical data.

    Result codes

            noErr       No error
            memFullErr  Not enough room in heap
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to operate on a free block
\ PtrToHand
25
FUNCTION PtrToHand (srcPtr: Ptr; VAR dstHndl: Handle; size: LONGINT) :
        OSErr;

    __________________________________________________________________

    Trap macro  _PtrToHand

    On entry    A0:  srcPtr (pointer)
                D0:  size (long word)

    On exit     A0:  dstHndl (handle)
                D0:  result code (word)
    ___________________________________________________________________





    PtrToHand returns in dstHndl a newly created handle to a copy of the
number of bytes specified by the size parameter, beginning at the
location specified by srcPtr.

    Result codes

            noErr       No error
            memFullErr  Not enough room in heap
\ PtrToXHand
25
FUNCTION PtrToXHand (srcPtr: Ptr; VAR dstHndl: Handle; size: LONGINT) :
                    OSErr;


    __________________________________________________________________

    Trap macro  _PtrToXHand

    On entry    A0:  srcPtr (pointer)
                A1:  dstHndl (handle)
                D0:  size (long word)

    On exit     A1:  dstHndl (handle)
                D0:  result code (word)
    ___________________________________________________________________

    PtrToXHand takes the existing handle specified by dstHndl and makes
it a handle to a copy of the number of bytes specified by the size
parameter, beginning at the location specified by srcPtr.

    Result codes

            noErr       No error
            memFullErr  Not enough room in heap
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to operate on a free block
\ HandAndHand
25
FUNCTION HandAndHand (aHndl,bHndl: Handle) : OSErr;

    __________________________________________________________________

    Trap macro  _PtrToXHand

    On entry    A0:  aHndl (handle)
                A1:  bHndl (handle)

    On exit     A1:  bHndl (handle)
                D0:  result code (word)
    ___________________________________________________________________

    HandAndHand concatenates the information to which aHndl is a handle
onto the end of the information to which bHndl is a handle.


    Result codes

            noErr       No error
            memFullErr  Not enough room in heap
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to operate on a free block
\ PtrAndHand
25
FUNCTION PtrAndHand (pntr: Ptr; hndlk: Handle; size: LONGINT) : OSErr;

    __________________________________________________________________

    Trap macro  _PtrToXHand

    On entry    A0:  pntr (pointer)
                A1:  hndl (handle)
                D0:  size (long word)

    On exit     A1:  hndl (handle)
                D0:  result code (word)
    ___________________________________________________________________

    PtrAndHand takes the number of bytes specified by the size
parameter, beginning at the location specified by pntr, and concatenates
them onto the end of the information to which hndl is a handle.

    Result codes

            noErr       No error
            memFullErr  Not enough room in heap
            nilHandleErr    NIL master pointer
            memWZErr    Attempt to operate on a free block
\ NGetTrapAddress
25
FUNCTION NGetTrapAddress (trapNum: INTEGER; tType: TrapType) : LongInt;
                            [Not in ROM]

    NGetTrapAddress is identical to GetTrapAddress except that it
requires you to specify in tType whether the given routine is an
Operating System or a Toolbox trap.

Trap macro  _GetTrapAddress ,NEWOS      (bit 9 set, bit 10 clear)
            _GetTrapAddress ,NEWTOOL    (bit 9 set, bit 10 set)

On entry    D0:  trapNum (word)

On exit     A0:  address of routine
\ NSetTrapAddress
25
FUNCTION NSetTrapAddress (trapAddr: LongInt; trapNum: INTEGER;
                            tType: TrapType);  [Not in ROM]

    NSetTrapAddress is identical to SetTrapAddress except that it
requires you to specify in tType whether the given routine is an
Operating System or a Toolbox trap.

Trap macro  _SetTrapAddress ,NEWOS      (bit 9 set, bit 10 clear)
            _SetTrapAddress ,NEWTOOL    (bit 9 set, bit 10 set)

On entry    A0:  trapAddr (address)
            D0:  trapNum (word)
\ RelString
25
FUNCTION RelString (aStr,bStr: Str255; caseSens,diacSens: BOOLEAN)
                    : INTEGER;

    RelString is similar to EqualString except that it indicates whether
the first string is less than, equal to, or greater than the second
string by returning either Đ1, 0, or 1 respectively.


Trap macro  _RelString
            _RelString ,MARKS       (sets bit 9, for diacSens=FALSE)
            _RelString ,CASE        (sets bit 10, for caseSens=TRUE)
            _RelString ,MARKS,CASE  (sets bits 9 and 10)

On entry    A0:  pointer to first character of first string
            A1:  pointer to first character of second string
            D0:  high-order word:  length of first string
                 low-order word:  length of second string

On exit D0:    Đ1 if first string less than second,
                0 if equal,
                1 if first string greater than second (long word)


    RelString follows the sort order described in chapter 19 of
Volume II except for the reordering of the following ligatures:

Ž falls between  and a
ž falls between  and B
Î falls between ¯ and o
Ī falls between ŋ and P
§ falls between s and T

    If diacSens is FALSE, diacritical marks are ignored; RelString
strips diacriticals according to the following table:

A   <Ņ  , , Ë, Ė
C   <Ņ  
E   <Ņ  
N   <Ņ  
O   <Ņ  , Í, ¯
U   <Ņ  
a   <Ņ  , , , , , , ģ
c   <Ņ  
e   <Ņ  , , , 
i   <Ņ  , , , 
n   <Ņ  
o   <Ņ  , , , , , ŋ, ŧ
u   <Ņ  , , , 
y   <Ņ  Ø

Note:   This stripping is identical to that performed by the UprString
        procedure when the diacSens parameter is FALSE.

    If caseSens is FALSE, the comparison is not case-sensitive;
RelString performs a conversion from lower-case to upper-case characters
according to the following table:

A   <Ņ  a
. . .   <Ņ  . . .
Z   <Ņ  z
Ë   <Ņ  
Ė   <Ņ  
   <Ņ  
   <Ņ  
Ž   <Ņ  ž
   <Ņ  
   <Ņ  
   <Ņ  
   <Ņ  
Í   <Ņ  
¯   <Ņ  ŋ
Î   <Ņ  Ī
   <Ņ  

Note:   This conversion is identical to that performed by the UprString
        procedure.

\ Environs
25
PROCEDURE Environs (VAR rom,machine: INTEGER)  [Not in ROM]

    In the rom parameter, Environs returns the current ROM version
number (for a Macintosh XL, the version number of the ROM image
installed by MacWorks). To use the 128K ROM  information described
in this volume, the version number should be greater than or equal
to 117 ($75). In the machine parameter, Environs returns an indication
of which machine is in use, as follows:


CONST   macXLMachine    = 0;    {Macintosh XL}
        macMachine      = 1;    {Macintosh 128K, 512K, 512K upgraded, }
                                { 512K enhanced, or Macintosh Plus}

Note:  The machine parameter does not distinguish between the Macintosh
128K, 512K, 512K upgraded, 512K enhanced, and Macintosh Plus.
________________________________________________________________________

Assembly-language note:  From assembly language, you can get this
information from the word thatÕs at an offset of 8 from the beginning
of ROM (which is stored in the global variable ROMBase). The format of
this word is $00xx for the Macintosh 128K, 512K, 512K upgraded, 512K
enhanced, or Macintosh Plus, and $xxFF for the Macintosh XL, where xx
is the ROM version number. (The ROM version number will always be
between $01 and $FE.)
________________________________________________________________________

\ EqualString
25
FUNCTION EqualString (aStr,bStr: Str255; caseSens,diacSens: BOOLEAN) :
                        BOOLEAN;

    _________________________________________________________________

    Trap macro  _CmpString
                _CmpString  ,MARKS          (sets bit 9, for
                                             diacSens=FALSE)
                _CmpString  ,CASE           (sets bit 10, for
                                             caseSens=TRUE)
                _CmpString   ,MARKS,CASE    (sets bits 9 and 10)


    On entry    A0:  pointer to first character of first string
                A1:  pointer to first character of second string
                D0:  high-order word: length of first string
                     low-order word:  length of second string

    On exit     D0:  0 if strings equal, 1 if strings not equal
                    (long word)
    ___________________________________________________________________

    EqualString compares the two given strings for equality on the basis
of their ASCII values. If caseSens is TRUE, uppercase characters are
distinguished from the corresponding lowercase characters. If diacSens
is FALSE, diacritical marks are ignored dring the comparison. The
function returns TRUE if the strings are equal.

(note)
    See also the International Utilities Package function
    IUEqualString, as described in the Macintosh Packages
    manual.
\ UprString
25
PROCEDURE UprString (VAR theString: Str255; diacSens: BOOLEAN);

    _________________________________________________________________

    Trap macro  _UprString
                _UprString  ,MARKS  (sets bit 9, for diacSens=FALSE)

    On entry    A0:  pointer to first charactaer of string
                D0:  length of string (word)

    On exit     A0:  pointer to first character of string
    __________________________________________________________________

    UprString converts any lowercase letters in the given string to
uppercase, returning the converted string in theString. In addition,
diacritical marks are stripped from the string if diacSens is FALSE.
\ ReadDateTime
25
FUNCTION ReadDateTime (VAR secs: LONGINT) : OSErr;

    __________________________________________________________________

    Trap macro  _ReadDateTime

    On entry    A0:  pointer to long word secs

    On exit     A0:  pointer to long word secs
                D0:  result code (word)
    __________________________________________________________________

    ReadDateTime copies the date and time stored in the clock chip to a
low-memory location and returns it in the secs parameter. This routine
is called at system startup; you'll probably never need to call it
yourself. Instead you'll call GetDateTime (see below).

    __________________________________________________________________

    Assembly-language note:  The low-memory location to which
    ReadDateTime copies the date and time is the global variable
    Time.
    __________________________________________________________________


    Result codes    noErr       No error
                    clkRdErr    Unable to read clock
\ GetDateTime
25
PROCEDURE GetDateTime (VAR secs: LONGINT);   [Not in ROM]

    GetDateTime returns in the secs parameter the contents of the low-
memory location in which the date and time is stored; if the date and
time is properly set, secs will contain the number of seconds between
midnight, January 1, 1904 and the time that the function was called.

(note)
    If your application disables interrupts for longer than a
    second, the number of seconds returned will not be exact.



    ________________________________________________________________

    Assembly-language note:  Assembly-language programmers can just
    access the global variable Time.
    ________________________________________________________________

    If you wish, you can convert the value returned by GetDateTime to a
date/time record by calling the Secs2Date procedure.

(note)
    Passing the value returned by GetDateTime to the
    International Utilities Package procedure IUDateString or
    IUTimeString will yield a string representing the
    corresponding date or time of day, respectively.
\ SetDateTime
25
FUNCTION SetDateTime (secs: LONGINT) : OSErr;

    _________________________________________________________________

    Trap macro  _SetDateTime

    On entry    D0:  secs (long word)

    On exit     D0:  result code (word)
    _________________________________________________________________

    SetDateTime takes a number of seconds since midnight, January 1,1904
as specified by the secs parameter and writes it to the clock chip as
the current date and time. It then attempts to read the value just
written and verify it by comparing it to the secs parameter.

    _________________________________________________________________

    Assembly-language note:  SetDateTime updates the global variable
    Time to the value of the secs parameter.
    _________________________________________________________________


    Result codes    noErr       No error
                    clkWrErr    Time written did not verify
                    clkRdErr    Unable to read clock
\ Date2Secs
25
PROCEDURE Date2Secs (date: DateTimeRec; VAR secs: LONGINT);

    _________________________________________________________________

    Trap macro  _Date2Secs

    On entry    A0:  pointer to date/time record

    On exit     D0:  secs (long word)
    _________________________________________________________________

    Date2Secs takes the given date/time record, converts it to the
corresponding number of seconds elapsed since midnight, January 1,
1904, and returns the result in the secs parameter. The dayOfWeek
field of the date/time record is ignored. The values passed in the
year and month fields should be within their allowable ranges, or
unpredictable results may occur. The remaining four fields of the
date/time record may contain any value. For example, September 35 will
be interpreted as October 4, and you could specify the 300th day of the
year as January 300.
\ Secs2Date
25
PROCEDURE Secs2Date (secs: LONGINT; VAR date: DateTimeRec);

    ________________________________________________________________

    Trap macro  _Secs2Date

    On entry    D0:  secs (long word)

    On exit     A0:  pointer to date/time record
    ________________________________________________________________


    Secs2Date takes a number of seconds elapsed since midnight,
January 1, 1904 as specified by the secs parameter, converts it to the
corresponding date and time, and returns the corresponding date/time
record in the date parameter.
\ GetTime
25
PROCEDURE GetTime (VAR date: DateTimeRec);   [Not in ROM]

    GetTime takes the number of seconds elapsed since midnight,
January 1, 1904 (obtained by calling GetDateTime), converts that value
into a date and time (by calling Secs2Date), and returns the result in
the date parameter.
\ SetTime
25
PROCEDURE SetTime (date: DateTimeRec);   [Not in ROM]

    SetTime takes the date and time specified by the date parameter,
converts it into the corresponding number of seconds elapsed since
midnight, January 1, 1904 (by calling Date2Secs), and then writes that
value to the clock chip as the current date time (by calling
SetDateTime).
\ InitUtil
25
FUNCTION InitUtil : OSErr;

    _________________________________________________________________

    Trap macro  _InitUtil

    On exit     D0:  result code (word)
    _________________________________________________________________


    InitUtil copies the contents of parameter RAM into 20 bytes of low
memory and copies the date and time from the clock chip into its own
low-memory location. This routine is called at system startup; you'll
probably never need to call it yourself.


    _________________________________________________________________

    Assembly-language note:  InitUtil copies parameter RAM into 20
    bytes starting at the address SysParam and copies the date and
    time into the global variable Time.
    _________________________________________________________________

    If the validity status in parameter RAM is not $A8 when InitUtil is
called, an error is returned as the result code, and the default values
(given earlier in the "ParameterRAM" section) are read into the los-
memory copy of parameter RAM; these values are then written to the
clock chip itself.

    Result codes    noErr       No error
                    prInitErr   Validity status not $A8
\ GetSysPPtr
25
FUNCTION GetSysPPtr : SysPPtr;   [Not in ROM]

    GetSysPPtr returns a pointer to the low-memory copy of parameter
RAM. You can examine the values stored in its various fields, or to
change them before calling WriteParam (below).
\ WriteParam
25
FUNCTION WriteParam : OSErr;

    _________________________________________________________________

    Trap macro  _WriteParam

    On entry    A0:  SysParam (pointer)
                D0:  MinusOne (long word)

                 (You have to pass the values of these global
                  variables for historical reasons.)

    On exit     D0:  result code (word)
    _________________________________________________________________


    WriteParam writes the low-memory copy of parameter RAM to the clock
chip. You should previously have called GetSysPPtr and changed
selected values as desired.

    WriteParam also attempts to verify the values written by reading
them back in and comparing them to the values in the low-memory copy.

(note)
    If you've accidentally written incorrect values into
    parameter RAM, the system may not be able to start up.
    If this happens, you can reset parameter RAM by removing
    the battery, letting the Macintosh sit turned off for
    about five minutes, and then putting the battery back in.


    Result code noErr       No error
                prWrErr     Parameter RAM written did not verify
\ Enqueue
25
PROCEDURE Enqueue (qElement: QElemPtr; theQueue: QHdrPtr);

    ________________________________________________________________

    Trap macro  _Enqueue

    On entry    A0:  qElement (pointer)
                A1:  theQueue (pointer)

    On exit     A1:  theQueue (pointer)
    ________________________________________________________________

    Enqueue adds the queue entry pointer to by qElement to the end of
the queue specified by theQueue.

(note)
    Interrupts are disabled for a short time while the queue
    is updated.
\ Dequeue
25
FUNCTION Dequeue (qElement: QElemPtr; theQueue: QHdrPtr) : OSErr;

    _________________________________________________________________

    Trap macro  _Dequeue

    On entry    A0:  qElement (pointer)
                A1:  theQueue (pointer)

    On exit     A1:  theQueue (pointer)
                D0:  result code (word)
    _________________________________________________________________


    Dequeue removes the queue entry pointed to by qElement from the
queue specified by theQueue (without deallocating the entry) and adjusts
other entries in the queue accordingly.

(note)
    The note under Enqueue above also applies here. In this
    case, the amount of time interrupts are disabled depends
    on the length of the queue and the position of the entry
    in the queue.

(note)
    To remove all entries from a queue, you can just clear
    all the fields of the queue's header.


    Result codes    noErr       No error
                    qErr        Entry not in specified queue




\ GetTrapAddress
25
FUNCTION GetTrapAddress (trapNum: INTEGER) : LONGINT;

    _________________________________________________________________

    Trap macro  _GetTrapAddress

    On entry    D0:  trapNum (word)

    On exit     A0:  address of routine
    _________________________________________________________________


    GetTrapAddress returns the address of a routine currently installed
in the trap dispatch table under the trap number designated by trapNum.
To find out the trap number for a particular routine, see Appendix B.
\ SetTrapAddress
25
PROCEDURE SetTrapAddress (trapAddr: LONGINT; trapNum: INTEGER);


    _________________________________________________________________

    Trap macro  _SetTrapAddress

    On entry    A0:  trapAddr (address)
                D0:  trapNum (word)
    _________________________________________________________________


    SetTrapAddress installs in the trap dispatch table a routine whose
address is trapAddr; this routine is installed under the trap number
designated by trapNum.

(note)
    Remember, the trap dispatch table can address locations
    within a range of 64K bytes from the base address of ROM
    or RAM.
\ Delay
25
PROCEDURE Delay (numTicks: LONGINT; VAR finalTicks: LONGINT);

    _______________________________________________________________

    Trap macro  _Delay

    On entry    A0:  numTicks (long word)

    On exit     D0:  finalTicks (long word)
    _______________________________________________________________

    Delay causes the system to wait for the number of ticks (sixtieths
of a second) specified by numTicks, and returns in finalTicks the total
number of ticks from system startup to the end of the delay.

(warning)
    Do not rely on the duration of the delay being exact; it
    will usually be accurate within one tick, but may be off
    more than that. The Delay procedure enables all
    interrupts and checks the tick count that's incremented
    during the vertical retrace interrupt; however, it's
    possible for this interrupt to be disabled by other
    interrupts, in which case the duration of the delay will
    not be exactly what you requested.
\ SysBeep
25
PROCEDURE SysBeep (duration: INTEGER);

    SysBeep causes the system to beep for approximately the number of
ticks specified by the duration parameter. The sound decays from loud
to soft; after about five seconds it's inaudible. The initial volume of
the beep depends on the current speaker volume setting, which the user
can adjust with the Control Panel desk accessory. If the speaker
volume has been set to 0 (silent), SysBeep instead causes the menu bar
to blink once.
\ LNew
26
FUNCTION LNew (rView,dataBounds: Rect; cSize: Point; theProc: INTEGER;
                theWindow: WindowPtr; drawIt,hasGrow,
                scrollHoriz,scrollVert: BOOLEAN) : ListHandle;

    Call LNew to create a new list. It returns a handle to the new list.
The listÕs grafPort is set to theWindowÕs port. If drawIt is FALSE,
the list is not displayed.

    RView specifies, in the local coordinates of theWindow, the
rectangle in which the list will be displayed. (Remember that this
doesnÕt include space for scroll bars. If the list, including scroll
bars, is to fill the entire window, rView should be 15 points smaller in
each dimension than theWindowÕs portRect.)

    DataBounds is the rectangle for specifying the initial array
dimensions of the list. For example to preallocate space for a list
thatÕs 5 cells across by 10 cells down, you should set dataBounds to
(0,0)(5,10). If you want to allocate the space for a one-column list,
set dataBounds to (0,0)(1,0) and use LAddRow.

    CSize.h and cSize.v are the desired height and width of each cell in
pixels; if theyÕre not specified, a default cell size is calculated
(as described above).

    TheProc is the resource ID of your list definition procedure; for
a text-only list, pass 0 and the default list definition procedure
(about 150 bytes in size) will be used. The list definition procedure
is called to initialize itself after all other list record fields have
been initialized; thus, it can use any of the values in the list record
(or set particular fields, such as the indent distance).

    If hasGrow is TRUE, the scroll bars are sized so that thereÕs room
for a size box in the standard position. ItÕs up to the program to
display the size box (using the Window Manager procedure DrawGrowIcon).
If scrollHoriz is TRUE, a horizontal scroll bar is placed immediately
below rView and all horizontal scrolling functions are implemented.
If scrollVert is TRUE, a vertical scroll bar is placed immediately to
the right of rView and all vertical scrolling functions are implemented.

    The visible rectangle is set to contain as many cells of cSize
(or the default) as will fit into rView. If the cells do not fit
exactly into rView, the visible rectangle is rounded up to the nearest
cell. Scrolling will always allow all cells to be fully displayed.
The selection flags are set to 0, and the active flag is set to TRUE.


Note:  Scrolling looks best if rView is a multiple of cSize.v in height.

\ LDispose
26
PROCEDURE LDispose (lHandle: ListHandle);

    Call LDispose when you are through using a list. It issues a close
call to the list definition procedure, and calls the Memory Manager
procedure DisposHandle for the data handle, the Control Manager
procedure DisposeControl for both scroll bars (if theyÕre there), and
DisposHandle for the list record.

Note:  Calling LDispose is much faster than deleting one row at a time.

\ LAddColumn
26
FUNCTION LAddColumn (count,colNum: INTEGER; lHandle: ListHandle)
                    : INTEGER;

    LAddColumn inserts into the given list the number of columns
specified by the count parameter, starting at the column specified by
colNum. Column numbers that are greater than or equal to colNum are
increased by count. If colNum is not within dataBounds, new last
columns are added. The number of the first added column is returned
and dataBounds.right is increased by count. All cells added are empty.
If there are no cells (because dataBounds.top = dataBounds.bottom), no
cells are added, but dataBounds is still extended. If drawing is on and
the added columns (which are empty) are visible, the list and its
scrollbars are updated.

\ LAddRow
26
FUNCTION LAddRow (count,rowNum: INTEGER; lHandle: ListHandle) : INTEGER;

    LAddRow inserts the number of rows specified by the count parameter,
starting at the row specified by rowNum. Row numbers that are greater
than or equal to rowNum are increased by count. If rowNum is not within
dataBounds, new last rows are added. The number of the first added row
is returned, and dataBounds.bottom is increased by count. All cells
added are empty. If there are no cells (because dataBounds.left =
dataBounds.right), no cells are added, but dataBounds is still extended.
If drawing is on and the added rows (which are empty) are visible, the
list and its scroll bars are updated.

\ LDelColumn
26
PROCEDURE LDelColumn (count,colNum: INTEGER; lHandle: ListHandle);

    LDelColumn deletes the number of columns specified by the count
parameter, starting with the column specified by colNum. Column
numbers that are greater than colNum are decreased by count. If colNum
is not within dataBounds, nothing is done. DataBounds.right is
decreased by count. If drawing is on and the deleted columns were
visible, the list and its scroll bars are updated.

    If count is 0, or colNum = dataBounds.left AND count  > =
dataBounds.right Đ dataBounds.left all the data in the list is quickly
deleted, dataBounds.right is set to dataBounds.left, and the number of
rows is left unchanged.

\ LDelRow
26
PROCEDURE LDelRow (count,rowNum: INTEGER; lHandle: ListHandle);

    LDelRow deletes the number of rows specified by the count parameter,
starting with the row specified by rowNum. Row numbers that are greater
than rowNum are decreased by count. If rowNum is not within dataBounds,
nothing is done. DataBounds.bottom is decreased by count. If drawing
is on and the deleted rows were visible, the list and its scroll bars
are updated.

    If count is 0, or rowNum = dataBounds.top AND count > =
dataBounds.bottom Đ dataBounds.top all the data in the list is quickly
deleted, dataBounds.bottom is set to dataBounds.top, and the number of
columns is left unchanged.

\ LAddToCell
26
PROCEDURE LAddToCell (dataPtr: Ptr; dataLen: INTEGER; theCell: Cell;
                        lHandle: ListHandle);

    LAddToCell appends the data pointed to by dataPtr and of length
dataLen to the cell specified by theCell in lHandle. If drawing is off,
you must turn drawing on and call LDraw (or LUpdate) to display the
cellÕs new value.

\ LClrCell
26
PROCEDURE LClrCell (theCell: Cell; lHandle: ListHandle);

    LClrCell clears the contents of the specified cell (by setting the
length to 0). If theCell is not a valid cell, nothing is done. If
drawing is off, you must turn drawing on and call LDraw to display
the cellÕs new value (or simply call the Window Manager procedure
InvalRect).

\ LGetCell
26
PROCEDURE LGetCell (dataPtr: Ptr; VAR dataLen: INTEGER; theCell: Cell;
                    lHandle: ListHandle);

    Given a cell in theCell, LGetCell copies the cellÕs data to the
location specified by dataPtr; dataLen is the maximum number of bytes
allowed. If the data is longer than dataLen, only dataLen bytes are
copied into the location specified by dataPtr. If the data is shorter
than dataLen, dataLen is set to the true length of the cellÕs data.

\ LSetCell
26
PROCEDURE LSetCell (dataPtr: Ptr; dataLen: INTEGER; theCell: Cell;
                    lHandle: ListHandle);

    LSetCell places the data pointed to by dataPtr and of length dataLen
into the specified cell. It replaces any data that was already in the
cell. If dataLen is 0, this is equivalent to LClrCell. If theCell is
not a valid cell, nothing is done. If drawing is off, you must turn
drawing on and call LDraw (or LUpdate) to display the cellÕs new value.

\ LCellSize
26
PROCEDURE LCellSize (cSize: Point; lHandle: ListHandle);

    LCellSize sets the cellSize field in the list record to cSize and
updates the visible rectangle to contain cells of this size. This
command should be used only before any cells have been drawn.

\ LGetSelect
26
FUNCTION LGetSelect (next: BOOLEAN; VAR theCell: Cell;
                    lHandle: ListHandle) : BOOLEAN;

    If next is FALSE, LGetSelect returns TRUE if the specified cell is
selected, or FALSE if not. If next is TRUE, LGetSelect returns in c the
cell coordinates of the next selected cell in the row that is greater
than or equal to theCell. If there are no more cells in the row, it
returns in theCell the cell coordinates of the next selected cell in the
next row. If there are no more rows, FALSE is returned.

\ LSetSelect
26
PROCEDURE LSetSelect (setIt: BOOLEAN; theCell: Cell;
                        lHandle: ListHandle);

    If setIt is TRUE, LSetSelect selects the cell and redraws if it is
visible and was previously unselected. If setIt is FALSE, it deselects
the cell and redraws if necessary.

\ LClick
26
FUNCTION LClick (pt: Point; modifiers: INTEGER; lHandle: ListHandle)
                    : BOOLEAN;

    Call LClick when there is a mouse-down event in the destination
rectangle or its scroll bars. Pt is the mouse location in local
coordinates. Modifiers is the modifiers word from the event record.
LHandle is the list to be tracked. The result is TRUE if a double-click
occurred (and the two clicks took place within the same cell).

    LClick keeps control until the mouse is released; each time through
its inner loop, it calls the routine whose pointer is in the lClikLoop
field of the list record.

    If the mouse is in the visible rectangle, cells are selected
according to the state of the modifiers and the selection flags. If the
mouse was in the cells but is dragged outside the listÕs rectangle, the
list is auto-scrolled. If the mouse was in a control, the controlÕs
definition procedure is called to track the mouse. To discover which
cell was clicked in, use the LLastClick function.

\ LLastClick
26
FUNCTION LLastClick (lHandle: ListHandle) : Cell;

    LLastClick returns the cell coordinates of the last cell clicked in.
If no cell has been clicked in since LNew, the value returned (for both
integers) is negative.

Note:   The value returned by this call is not the last cell
        double-clicked in, or the last cell selected, but merely the
        last cell clicked in.

\ LFind
26
PROCEDURE LFind (VAR offset,len: INTEGER; theCell: Cell;
                    lHandle: ListHandle);

    Given a cell in theCell, LFind returns the offset and the length in
bytes of the cellÕs data. If an invalid cell is specified, offset and
len are set to Đ1. A similar procedure, LGetCell, is more convenient to
use from Pascal.

\ LNextCell
26
FUNCTION LNextCell (hNext,vNext: BOOLEAN; VAR theCell: Cell;
                    lHandle: ListHandle) : BOOLEAN;

    Given a cell in theCell, LNextCell returns in theCell the next cell
in the list. If both hNext and vNext are TRUE, theCell is first
advanced to the next cell in the row. If there are no more cells in the
row, theCell is set to the first cell in the next row. If there are no
more rows, FALSE is returned. If only hNext is TRUE, theCell is
advanced within the current row. If only vNext is TRUE, theCell is
advanced within the current column. FALSE is returned if there are no
remaining cells in the row or column.

\ LRect
26
PROCEDURE LRect (VAR cellRect: Rect; theCell: Cell; lHandle: ListHandle)

    LRect returns in cellRect the local (QuickDraw) coordinates of the
cell specified by theCell. If an invalid cell is specified, (0,0)(0,0)
is returned in cellRect.

\ LSearch
26
FUNCTION LSearch (dataPtr: Ptr; dataLen: INTEGER; searchProc: Ptr;
                    VAR theCell: Cell; lHandle: ListHandle) : BOOLEAN;

    LSearch searches for the first cell greater than or equal to theCell
that contains the specified data. If a cell containing matching data is
found, the function result TRUE is returned, and the cell coordinates
are returned in theCell. If searchProc is NIL, the International
Utilities Package function IUMagIDString is called to compare the
specified data with the contents of each cell. If searchProc is not
NIL, the routine pointed to by searchProc is called.

Note:  Your searchProc should have the same parameters as the
        IUMagIDString function.

\ LSize
26
PROCEDURE LSize (listWidth,listHeight: INTEGER; lHandle: ListHandle);

    YouÕll usually call LSize immediately after the Window Manager
procedure SizeWindow. It causes the bottom right of the list to be
adjusted so that the list is the width and height indicated by listWidth
and listHeight. The contents of the list and the scroll bars are
adjusted and redrawn as necessary. The values of listWidth and
listHeight do not include the scroll bars; for a list that entirely
fills the window, listWidth and listHeight should be 15 less than the
portRect if both scroll bars are present.

\ LDraw
26
PROCEDURE LDraw (theCell: Cell; lHandle: ListHandle);

    Call LDraw after updating a cellÕs data or selection status. (You
can achieve the same result by invalidating the cellÕs rectangle and
calling LUpdate in response to the update event.)  The List Manager
makes its grafPort the current port, sets the clipping region to
the cellÕs rectangle, and calls the list definition procedure to draw
the cell. It restores the clipping region and port before exiting.

\ LDoDraw
26
PROCEDURE LDoDraw (drawIt: BOOLEAN; lHandle: ListHandle);

    LDoDraw sets the List ManagerÕs drawing mode to the state specified
by drawIt. If drawIt is TRUE, changes made by most List Manager calls
will cause some sort of drawing to take place. If drawIt is FALSE, all
cell drawing is disabled. (Two exceptions:  The scroll bars are still
updated after LSize, and the scroll arrows are still highlighted if the
user clicks them.)

    The recommended use of LDoDraw is to disable drawing while youÕre
building a list (that is, adding rows or columns, setting or changing
cell values, or setting default selections). Once youÕve finished
building the list, you should then re-enable drawing. In general,
drawing should be on while youÕre in your event loop and dispatching
events to the List Manager.

\ LScroll
26
PROCEDURE LScroll (dCols,dRows: INTEGER; lHandle: ListHandle);

    LScroll scrolls the given list by the number of columns and rows
specified in dCols and dRows, either positively (down and to the right)
or negatively (up and to the left). Scrolling is pinned to the listÕs
dataBounds. If drawing is on, LScroll does all necessary updating of
the screen.

\ LAutoScroll
26
PROCEDURE LAutoScroll   (lHandle: ListHandle);

    For the given list, LAutoScroll scrolls the list until the first
selected cell is visible. It automatically places the first selected
cell in the top left corner of the visible rectangle.

\ LUpdate
26
PROCEDURE LUpdate (theRgn: RgnHandle; lHandle: ListHandle);

    LUpdate should be called in response to an update event. TheRgn
should be set to the visRgn of the listÕs port (for more details, see
the BeginUpdate procedure in the Window Manager chapter). It redraws
any visible cells in lHandle that intersect theRgn. It also redraws
the controls, if necessary.

\ LActivate
26
PROCEDURE LActivate (act: BOOLEAN; lHandle: ListHandle);

    Call LActivate to activate or deactivate the list specified by
lHandle (in response to an activate event in the window containing the
list). The act parameter should be set to TRUE to activate the list, or
FALSE to deactivate the list. LActivate highlights or unhighlights the
selections, and shows or hides the scroll bars (but not the size box, if
any).